From 8dee0f0ae97df294e20e9b100f40a77c06bde9a7 Mon Sep 17 00:00:00 2001
From: Rob Manson <rob.manson@awe.media>
Date: Fri, 15 Mar 2019 18:41:25 +1100
Subject: [PATCH] First stage of updating this repos with how-to guides to help
 you create your own Augmented Web Experiences (awe apps) using the awe.media
 platform.

The previous version of this repos is now available on the `deprecated` branch.
---
 README.md                                     |   478 +-
 examples/basic/ar.html                        |   201 -
 examples/basic/awe.gyro.js                    |    83 -
 examples/basic/awe.mouse.js                   |   145 -
 examples/basic/vr.html                        |   200 -
 examples/marker_ar/64.png                     |   Bin 197 -> 0 bytes
 .../marker_ar/awe-jsartoolkit-dependencies.js | 11646 ----------------
 examples/marker_ar/awe.marker_ar.js           |   524 -
 examples/marker_ar/awe_orange_square.png      |   Bin 23010 -> 0 bytes
 examples/marker_ar/index.html                 |   129 -
 examples/stereo_ar/awe.stereo_click.js        |    99 -
 examples/stereo_ar/awe_by_buildAR.png         |   Bin 13460 -> 0 bytes
 examples/stereo_ar/index.html                 |   229 -
 js/awe-loader-min.js                          |     1 -
 js/awe-loader.js                              |  1217 --
 js/awe-standard-dependencies.js               |  5702 --------
 js/awe-standard.js                            |  4472 ------
 js/awe-v8.js                                  |   769 -
 js/plugins/StereoEffect.js                    |   126 -
 js/plugins/VREffect.js                        |   262 -
 js/plugins/awe-standard-object_clicked.js     |    80 -
 .../awe-standard-object_clicked_or_focused.js |   311 -
 js/plugins/awe-standard-object_focused.js     |   252 -
 js/plugins/awe.rendering_effects.js           |   414 -
 package.json                                  |    30 -
 25 files changed, 396 insertions(+), 26974 deletions(-)
 delete mode 100755 examples/basic/ar.html
 delete mode 100644 examples/basic/awe.gyro.js
 delete mode 100644 examples/basic/awe.mouse.js
 delete mode 100755 examples/basic/vr.html
 delete mode 100755 examples/marker_ar/64.png
 delete mode 100755 examples/marker_ar/awe-jsartoolkit-dependencies.js
 delete mode 100755 examples/marker_ar/awe.marker_ar.js
 delete mode 100644 examples/marker_ar/awe_orange_square.png
 delete mode 100755 examples/marker_ar/index.html
 delete mode 100755 examples/stereo_ar/awe.stereo_click.js
 delete mode 100755 examples/stereo_ar/awe_by_buildAR.png
 delete mode 100755 examples/stereo_ar/index.html
 delete mode 120000 js/awe-loader-min.js
 delete mode 100755 js/awe-loader.js
 delete mode 100755 js/awe-standard-dependencies.js
 delete mode 100644 js/awe-standard.js
 delete mode 100755 js/awe-v8.js
 delete mode 100644 js/plugins/StereoEffect.js
 delete mode 100644 js/plugins/VREffect.js
 delete mode 100755 js/plugins/awe-standard-object_clicked.js
 delete mode 100644 js/plugins/awe-standard-object_clicked_or_focused.js
 delete mode 100755 js/plugins/awe-standard-object_focused.js
 delete mode 100644 js/plugins/awe.rendering_effects.js
 delete mode 100644 package.json

diff --git a/README.md b/README.md
index 8111b7f..c689de6 100644
--- a/README.md
+++ b/README.md
@@ -1,137 +1,451 @@
-awe.js
-======
-
 awe.media is hiring
 -------------------
 If you're an experienced javascript developer and you're interested in pushing the boundaries of Virtual and Augmented Reality or Computer Vision then contact us through `jobs [ at ] awe.media`.
 
-What is awe.js?
----------------
-It's the quickest and easiest way to create Augmented Web applications.
+# This is your 'how to' guide to creating awe apps
+
+This page is for people interested in creating web-based Immersive experiences (Augmented Reality, Virtual Reality, Interactive 360° Scenes, Mixed Reality, etc.) using awe.js on the the [awe.media](https://awe.media) platform.
+
+It provides you with an overview of the different 'how-to' guides that are available to show you how to use different features and concepts when creating your own awe app.
+
+If you have any questions or need any other information please contact our [support team](mailto:support@awe.media). We love to help people get the best out of the awe platform.
+
+- [How do I create an awe app?](#how-do-i-create-an-awe-app)
+- [How do I test and share my awe app?](#how-do-i-test-and-share-my-awe-app)
+- [How do I add content to my awe app?](#how-do-i-add-content-to-my-awe-app)
+- [What types of experiences can I create?](#what-types-of-experiences-can-i-create)
+- [Are there any quick keys in the creator UI](#are-there-any-quick-keys-in-the-creator-ui)
+- [Getting started writing custom code for my awe app](#getting-started-writing-custom-code-for-my-awe-app)
+- [What are the types of objects in my awe app?](#what-are-the-types-of-objects-in-my-awe-app)
+  - [awe](#awe)
+  - [application](#application)
+  - [apps](#apps)
+  - [capabilities](#capabilities)
+  - [settings](#settings)
+  - [scenes](#scenes)
+  - [views](#views)
+  - [assets](#assets)
+  - [files](#files)
+  - [pois](#pois)
+  - [projections](#projections)
+  - [events](#events)
+  - [actions](#actions)
+  - [animations](#animations)
+  - [povs](#povs)
+  - [video streams](#video-streams)
+  - [plugins](#plugins)
+
+## How do I create an awe app?
+To get started you can [create a free trial at try.awe.media](https://try.awe.media). This lets you explore what you can create with your own awe app. This will setup your own awe app domain (e.g. `1234abcd.awe.io`), and all the experiences you create will be accessible as pages under this domain (e.g. `https://1234abce.awe.io/my-first-webar-experience`).
+
+Once you've explored your free trial and you're ready to turn it into a real project you can activate your awe app. This will give you control over publishing your awe app (e.g. if you want it to be public for others to view), plus unlock other features so you can add more custom Javascript and CSS, etc. It will also add additional views to your app so you can create up to 5 of [each type of experience](#what-types-of-experiences-can-i-create).
+
+Beyond that, you can also purchase more value added features including additional views (e.g. AR images/3D scenes/pages), increase your upload limits, add your own custom domain and add your own custom branding. You can even fully remove all awe branding to create your own white-label experience.
+
+## How do I test and share my awe app?
+To share your creation all you need to do is share the web link to your awe app (e.g. `https://1234abcd.awe.io`). You can even deep link directly to a specific experience you have created (e.g. `https://1234abce.awe.io/my-first-webar-experience`). 
+
+All anyone needs to do to try your experience is open this web link in the browser on their computer or in their pocket. No apps to download or install. It works on over 3 Billion web browsers around the world - including iPhones, Androids, Computers and Head Mounted Displays.
+
+(After our next release) During your trial you can share your creation with anyone and it can be viewed up to 50 times. After that it will be placed in `private mode` and you will need to activate your app to make it public again.
+
+If your app is in `public mode`, then when other people access your app they will see the experience you have created without any of the `creator` options.
+
+## How do I add content to my awe app?
+If your awe app is in `private mode` then you will need to sign-in on any device you use to view and edit your creation. When you are signed-in you will see your app in the `creator` mode. Using this friendly web UI you can easily upload `images`, `videos` (including alpha/greenscreen videos), `3D objects`, `3D animated clips`, `audio` files and `AR target images` to your awe app. You can do this from your computer, tablet or mobile device and the whole `creator` experience is very similar across all devices.
+
+You can then simply add these media assets to your 3D scenes, lay them out and add actions and interactivity to create rich and immersive experiences.
+
+## What types of experiences can I create?
+You can think of your awe app as a single page web app. Under your top level awe app domain (e.g. `https://1234abcd.awe.io`) you can create individual pages. These pages are a combination of HTML content, a 3D scene, additional interactivity and animations, plus AR or VR functionality. We call these combinations `views` as they are what your end users look at and they provide a unique view onto the real world or into a virtual world.
+
+The 3 main types of experience you can create are:
+- image: These are image or `Natural Feature Tracking` based AR experiences that let you glue digital objects onto images in the real world
+- standard: These are 360° or VR experiences that work on computers, mobiles and head mounted displays with controllers
+- location: These are location based AR experiences that use GPS to place objects in the real world
+
+NOTE: [awe.media](https://awe.media) is the only platform in the world that provides **Natural Feature Based** image tracking in the web!
 
-If you want to see what an awe.js app looks like just visit https://awe.media and setup a free demo.
+One of the most powerful features of your awe app is that it makes it easy to seamlessly link from one type of experience to another, all within the same app. For example:
+- You might want your end users to start by scanning a QR code or entering a web link. 
+- This can then open their camera through their browser to let them view AR overlaid onto a poster. 
+- Once they've interacted with this poster you may drive them to unlock a location based experience (e.g. a treasure hunt) that leads them around the local area. 
+- And once they find a specific item you've hidden in a specific place then this may unlock an interactive 360° experience. 
+This is just one simple scenario that shows how you could blend different modes into one seamless experience using a single awe app. The creative options here are endless.
 
-Here's a few short videos that show you just how easy it is to create an awe app.
-- Add a 360° photo or video background https://youtu.be/B2mQaeXyXDw
-- Add 3D objects, images or videos https://youtu.be/LxVRBxC-SHY
-- Add interactivity https://youtu.be/3N2NZfCCuLY 
+**Stay tuned because we have some exciting new modes and options we'll be announcing soon!**
 
-Or checkout some of our older demos showing showing different uses of awe.js 
-- Location based AR http://youtu.be/OJHgBSRJNJY
-- Marker based AR http://youtu.be/X_XR9VbQPeE
-- Oculus Rift based AR http://youtu.be/kIHih4Cc1ag
-- Leap Motion Sensor AR http://youtu.be/mDbvPU4aokQ
-- Google Glass AR http://youtu.be/M97E2m6dRO4
+## Are there any quick keys in the creator UI
+If you are signed-in as a `creator` on your computer browser you can use the following quick keys.
 
-awe.js docs
------------
-Checkout the docs in our [wiki](https://github.com/awe-media/awe.js/wiki).
+- O for object editor
+- B for background (only available in standard views)
+- T for target image (only available in image views)
+- L for live preview
+- S for scan (only available in image views)
 
-What is the Augmented Web?
---------------------------
-It's what comes after html5!
+Of course you can use the `creator` UI on your mobile devices too, but quick keys are not supported there.
 
-It uses WebRTC, WebGL, WebVR and the modern sensor APIs to bring Augmented Reality and so much more to the web platform. It will completely change the way you and your users see the web.
+## Getting started writing custom code for my awe app
+Now lets look at an overview of the different places where you can add custom Javascript and CSS within your awe app. This will introduce you to the key concepts that make your awe app work.
 
+To get started you'll want to enable console output in your awe app. We have turned this off to reduce overhead and prevent our production awe apps from polluting the browser console. But to interact during development you want to turn this on. 
 
-How do you create an awe.js app?
---------------------------------
-Just add a `<script src='js/awe.js'></script>` tag to your html page to turn that page into an Augmented Web application.
+Copy this line into your Javascript console and hit enter, then reload your page.
+```
+document.cookie="enable_console=1"
+```
+
+## What are the types of objects in my awe app?
+Below we outline 17 key Javascript objects you can work with when creating custom code for your awe app. By convention all awe related objects and functions use all lower case with underscores. This makes it easy to differentiate awe related objects and functions from APIs and objects provided by the browser.
+
+Another key part of your awe app is the orange circle that sits in the bottom left hand corner of your window. We call this the awe `doodat`. If you are signed-in as a `creator` then the `doodat` will almost always be there and you can use this to access the different modes and editing tools. 
+
+However, as a `creator` you can choose whether you want your end users to see the `doodat` or not. It does provide a useful UI that lets them easily change mode, etc. But if you want to remove some or all of the awe branding then you can contact our [support team](mailto:support@awe.media) to purchase the ability to hide the `doodat`.
 
-Now you are ready to create adaptive Augmented Web Experiences. `awe.js` allows you to easily create and manage 3d objects, add and manage Video and Audio streams and integrate automatic handling of sensor driven data feeds.
+### awe
+The `awe.js` API is made available through the `awe` object in the DOM. `awe.js` was first released in 2012 and was the first Immersive Web Javascript framework released. Since then we have moved the version of `awe.js` that was in this github repository to the `deprecated` branch and the latest version is now available inline as part of your `awe.media` awe app. This latest version includes a wide range of enhancements and new features that are not included in the `deprecated` branch on github. This repos is now focused on providing guides and examples of how to create immersive web-based experiences using `awe.media` based awe apps.
 
-See the `examples/` and their plugins for more details.
+Most of the objects within the `awe` object are based on a type of datastore using the [awe v8 api](/awe-v8-api). This simple and consistent API is along the lines of the database style [CRUD model](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) - but instead it focuses on 8 key verbs.
 
-To initialize your `awe.js` application just call: 
+- search
+- list
+- add
+- view
+- edit
+- update
+- delete
+- report
 
+These verbs let you access and manage the objects stored in a datastore (e.g. `awe.projections.list()`). Once you have accessed a specific object you can get at the detailed information it contains by calling the `.get_data()` method. And in specific cases key data or functions are made available at the top level of the object too.
+
+If you want to update a specific object you can then use the `.update()` method in one of 2 ways. You can use the full and verbose method e.g.
 ```
-awe.init({
-  ...
+awe.projections.update({
+  data: {
+    position:{ x:0, y:0, z:-100 }
+  },
+  where: {
+    id: 1234,
+  }
+});
+```
+Or if you already have a reference to the specific object (e.g. projection id 1234) then you can use the simpler method e.g.
+```
+var projection = awe.projections.view(1234);
+projection.update({
+  position:{ x:0, y:0, z:-100 }
 });
 ```
 
-Once the `awe_ready` event is fired then your `awe.js` app is ready to start. Then you can call `awe.setup_scene()` to setup your scene. NOTE: This must be called after `awe_ready` has been fired.
+The `awe.js` API sits on top of `THREE.js` and makes it easy for you to manage scenes, media objects, interactivity, sensors, device types and more. The guides listed below provide detailed examples of how to use this API where relevant.
 
-To see this working try loading `examples/basic/index.html` in a suitable standards compliant browser.
+### application
+Much of the `awe.media` specific functionality is made available through the `application` object in the DOM. This provides some key utilities and also lets you access information about the current `app`, current `view`, configuration and more. The guides listed below provide detailed examples of how to use this API where relevant.
 
-How do you add objects to your scene?
--------------------------------------
-The `awe.js` API is consistently built upon a simple CRUD like model but the common actions are named `list`, `add`, `view`, `update` and `delete` - see the `v8.js` file included in the top of `js/awe.js` for more detailed information.
+### apps
+Your awe app is represented by an `awe_app` object that is a type of `awe_object`. You can access all the awe `apps` loaded using the `awe.js` API e.g.
+```
+awe.apps.list();
+```
+Alternatively, you can access the current `app` using the `application` API e.g.
+```
+application.current_app
+```
 
-Each `awe.js` application consists of a 3d scene and into that scene you can add points of interest or pois. Each poi marks out a point in space that is important or useful for some reason. This can be the location of an object or it might be a point where a recognised object or marker is currently sitting. Then you can attach different types of media (e.g. 3d objects, videos, images and sounds) to each poi and these pieces of media are called projections.
+Generally it is best to manage the configuration of your `app` through the `awe.media` creator UI. Then you can access this `app` configuration at runtime to make decisions that can dynamically update your experience.
 
-To add an object (point of interest) into your scene just call:
+### capabilities
+Each device has a specific set of capabilities that allow it to deliver content and interactivity. By detecting the capabilities you device provides `awe` is able to classify the unique interaction and content it can present to you. You can access the capabilities of the current device through the `awe` API e.g.
+```
+awe.capabilities.list()
+```
 
+The list of key capabilities that `awe` tests for are:
+- ajax (ability to make service requests via xhr or fetch)
+- audio (ability to use the WebAudio API to load and play sounds)
+- geo (ability to access the Geolocation API - on mobile this is driven by GPS)
+- gum (ability to access the devices Camera and Microphone)
+- gyro (ability to access the DeviceOrientation or similar API to detect the devices pose)
+- javascript_w3c (ability to use some specific javascript features required)
+- motion (ability to access the DeviceMotion API to detect acceleration & gravity)
+- sockets (ability to access the WebSockets API to send bi-directional real-time messages)
+- storage (ability to access localStorage to persist key data)
+- touch (ability to access user input through touch)
+- webgl (ability to access the WebGL API to present 3D scenes)
+
+### settings
+Important values that define how your awe app is configured are stored in the global awe `settings` datastore. You can access this through the `awe` API e.g.
 ```
-awe.pois.add({ id: 'my_first_poi' });
+awe.settings.list()
 ```
 
-To see all the points of interest in the scene call:
+You can also turn on and off key features within the standard interaction model by updating specific settings e.g.
+```
+awe.settings.update({ 
+  data: { value: true }, 
+  where: {id: 'prevent_pan_and_zoom' } // set value to true to turn off pan/pinch/zoom in standard views
+});
+```
+
+Generally it is best to manage the configuration of your `settings` through your awe app creator UI.
+
+### scenes
+The 3D part of your experience is represented by an awe `scene`. This lets you load, display and interact with media in a spatial way. Your scenes can be view in the `magic window` model, or what awe calls `view_mode:mono`. Or you can render it for 2 eyes so you can view it in a Head Mounted Display or similar, which awe calls `view_mode:stereo`. Your users can easily switch between `mono` and `stereo` mode in `standard` and `location` based views by selecting the `doodat` and clicking on the `live` or `stereo` icons in the `view control` panel.
 
+You can easily jump between these 2 modes using the `application` API e.g.
 ```
-awe.pois.list();
+application.show_stereo();
+application.show_mono();
 ```
 
-To see the first poi you created call: 
+You can access your scenes through the `awe` API e.g.
+```
+awe.scenes.list()
+```
 
+Or you can access the default, or primary scene through the `awe` API e.g.
 ```
-var poi = awe.pois.view('my_first_poi');
+awe.scene()
 ```
 
-To see all the projections in the scene call:
+You will also find a wide range of useful functions attached to this scene object.
+
+
+### views
+Each interactive experience you create has it's own page (e.g. `https://1234abce.awe.io/my-first-webar-experience`). However, this is more than a normal web page - it's an awe `view`. This is a combination of the HTML overlay content, a WebGL based 3D scene that contains interactive objects, actions and animations that bind them all together and custom Javascript and CSS that can extend them to enhance the way the look and behave. These are all then linked together with unique AR and VR functionality to let you create truly immersive web-based experiences.
 
+You can access access your `views` through the `awe.js` API e.g.
 ```
-awe.projections.list();
+awe.views.list()
 ```
 
-To rotate a poi and all it's children projections just call:
+Or you can access the current `view` through the `application` API e.g.
+```
+application.current_view
+```
+
+Also, using the editor UI you can easily add actions that link from one `view` to another. Just go to the object editor and select the object you want. Then select the `...` button in the bottom right corner, then select `Actions` and add an `On select` action. Then select `Load view` and select the `view` you want to link to. Now you can open the doodat and go to the `live preview` mode. When you select that object (e.g. click or tap on it) then it will load the view you specified.
+
+Of course you can do the same sort of thing directly from Javascript using the `application` API e.g.
+```
+application.load_view('my-first-webar-experience'); // use any valid view name that exists
+```
 
+### assets
+Assets represent a collection of media and configuration that can be added into a 3D scene. If you are signed in as a `creator` and are in the object editor mode, then in the bottom right hand corner you'll see an orange tab hanging out from the side of the viewport. This is your media library, and when you upload files here they will be transcoded into various sizes and formats required for all the different browsers and stored as `assets`.
+
+Generally it is best to manage the configuration of your `assets` through the media library in your awe app. Then you can access their configuration at runtime to make decisions that can dynamically update your experience e.g.
+```
+application.current_app.assets
 ```
-awe.pois.update({
-  data:{
-    rotation:{
-      y:180
+
+### files
+As mentioned above, each `file` that is uploaded to your media library is transcoded into various sizes and formats and converted into an `asset`. 
+
+These files can be images (png, jpg, static gif, tif, bmp, etc.), video (.mp4, .avi and .mov including alpha/greenscreen videos), static objects (.obj/.mtl/textures files all in a single .zip), animated objects (.fbx files with any external textures in a single .zip) & audio (.mp3, .aiff, etc.).
+
+You can access the list of `files` related to each `asset` within that specific `asset` object e.g.
+```
+var my_asset = application.current_app.assets[1234];
+var my_files = my_asset.files;
+``` 
+
+You can access the individual `asset` id's through the media library UI. Just click on the `(i)` button in the bottom right hand corner of the thumbnail of each `asset`.
+
+### pois
+In order to place any object within a 3D scene you need to identify a point in that 3D space. `pois` are objects that represent a `Point Of Interest` and they allow you to attach other objects to them. You can them move these `pois` around by updating their position. All objects attached to these `pois` will then move in a relative way. You can also adjust a `poi's` rotation, scale and visible values to transform or show & hide them and all their children.
+
+You can access `pois` through the `awe` API e.g.
+```
+awe.pois.list()
+```
+
+Or if you have a specific `poi` object already then you can transform it using the `awe` API e.g.
+```
+var poi = awe.pois.view(123);
+poi.update({
+  position:{ x:0, y:0, z:-100 })
+});
+```
+
+
+### projections
+The objects that are projected into your scene that are actually seen by the end users are called `projections`. These use `assets` and their `files` to construct 3D objects. Each `projection` is generally attached to a `poi` as it's parent, however `pois` and `projections` can be dynamically nested arbitrarily.
+
+Through the creator UI we allow you to easily layout and create these structures with an easy to use drag'n'drop interface. However, at runtime you can create and modify these `pois` and `projections` through the `awe` API e.g.
+```
+awe.projections.list()
+```
+
+Or if you have a specific `projection` object already then you can transform it using the `awe` API e.g.
+```
+var projection = awe.projection.view(456);
+projection.update({
+  position:{ x:0, y:0, z:-100 }),
+  visible:true,
+  material:{
+    opacity: 0.5
+  }
+});
+```
+
+You can also move a projection from one parent to another using the `awe` API e.g.
+```
+var projection = awe.projection.view(456);
+projection.update({
+  parent: {
+    object_type:'poi', // this is the type of the new parent (e.g. poi, projection or pov)
+    object_id:789}, // this is the id of the new parent object
+    retain_world_position: true // stay in the same world position or move relative to new parent
+  }
+});
+```
+
+### events
+When you configure interactivity using the creator UI your awe app will setup a specific `event` object. Depending on the type of object you are adding them to they can be `On load` (e.g. when the object loads), `On select` (e.g. when the object it clicked or tapped), `On play` (e.g. when the media starts playing), etc.
+
+You can access these `events` through the `application` API e.g.
+```
+application.current_app.events
+```
+
+### actions
+When you configure interactivity using the creator UI your awe app will setup a specific `action` object. Depending on the type of object you are adding them to they can be `On load` (e.g. when the object loads), `On select` (e.g. when the object it clicked or tapped), etc.
+
+You can access these `actions` through the `application` API e.g.
+```
+application.current_app.actions
+```
+
+### animations
+When you configure `animations` using the creator UI your awe app will setup a specific `animation` object. These animations can be awe based animations or pre-defined 3D clip animations.
+
+You can access these `animations` through the `application` API e.g.
+```
+application.current_app.animations
+```
+
+You can also easily create `animations` through Javascript using the `awe` API. Just add an `animation` block to your `.update()` call e.g.
+```
+var projection = awe.projection.view(456);
+projection.update({
+  position:{ x:0, y:0, z:-100 }),
+  animation:{
+    duration:5, // take 5 seconds to complete the animation
+    persist:1, // stay at the end state when the animation is complete
+    end_callback:function() {
+      // do something else when the animation is complete
     }
-  },
-  where:{
-    id:'my_first_poi'
   }
 });
 ```
 
-NOTE: It's important that you only manipulate your pois and projections using the `awe.js` interface (e.g. `awe.pois.update({ data:{...}, where:{...} }`) otherwise you will miss out on all the `awe.js` automagic goodness.
+These type of `animations` in `awe` are created using the [TWEEN.js library](https://github.com/tweenjs/tween.js/blob/master/docs/user_guide.md). The `TWEEN` object is automatically loaded and available in the DOM within your awe app so you can also use that to create any other custom HTML animations etc.
+
+You can also access the `animations` objects for running animations through the `awe` API e.g.
+```
+awe.animations.list()
+```
+
+
+### povs
+Your view into your 3D scene is created by a virtual camera. In `awe` we call these a `Point Of View` or `pov` for short. These `povs` have a very similar API to `pois` and `projections` and can be moved around and rotated in a very similar way. But be aware that specific `view` types on specific device types may override or manage the position and configuration of your `pov` automatically. For example, in AR it is important for the position and orientation of the `pov` to be closely matched to the position and orientation, etc. of the real world camera that's providing the video stream seen in the background of the scene. If you alter this then the illusion created by AR may be broken or diminished.
+
+You can access `povs` through the `awe` API e.g.
+```
+awe.povs.list()
+```
+
+Or you can access the default or primary `pov` directly through the `awe` API e.g.
+```
+awe.pov()
+```
 
+### video streams
+In order to create the illusion of see-thru AR, we will often present a video stream from the devices camera in the background of the scene. And many devices have more than one camera so it is possible to setup more than one stream. You can access these streams through the `awe` API e.g.
+```
+awe.video_streams.list()
+```
 
-Example pois.add data structure 
--------------------------------
+Or you can access the default or primary video stream (if it is setup) through the `awe` API e.g.
 ```
-{
-  id: 'poi_name',
-  scale: { x:1, y:1, z:1 },
-  position: { x:1, y:1, z:1 },
-  rotation: { x:0, y:0, z:0 },
-  visible: true,
-}
+awe.video_stream()
 ```
 
-Example projections.add data structure  
---------------------------------------
+We have also made it as simple as possible to turn on and off these video streams and automatically place them into the background of the scene. This is effectively flipping between AR and VR modes. You can turn on AR mode using the `application` API e.g.
 ```
-{
-  id: 'projection_name',
-  scale: { x:1, y:1, z:1 },
-  position: { x:1, y:1, z:1 },
-  rotation: { x:0, y:0, z:0 },
-  geometry: { shape:'cube', x:10, y:10, z:10 },
-  material: { color:0xFF0000, opacity:1.0, transparent:true, wireframe:false, fog:true },
-  texture: { path:'example.jpg' },
-  visible: true,
-  cast_shadow: true,
-  receive_shadow: true,
-},
-{
-  poi_id:'poi_name',
-}
+application.show_ar()
 ```
 
-Welcome to the future of the web - the Augmented Web!
+NOTE: This simply turns on the camera and does not necessarily start any specific type of AR plugin (see below).
+
+Or alternatively, you can switch back to VR/360° mode using the `application` API e.g.
+```
+application.show_vr()
+```
+
+### plugins
+There is a standard format for extending the `awe` API which is based on a `plugin` model. Your awe app comes with several standard plugins already loaded including one for detecting object interactions, one for handling mobile based gyro driven scene, one for QR code detection and one for image based natural feature tracking. You can access the `plugins` through the `awe` API e.g.
+```
+awe.plugins.list()
+```
+
+## Detailed 'how-to' guides on specific topics
+Below is a collection of detailed 'how-to' guides that will help you complete a specific goal or objective. They assume you have read the content above and include all the relevant Javascript, CSS and HTML snippets you may require.
+
+If you have an idea for another 'how-to' guide please contact [support team](mailto:support@awe.media). We'd love to hear from you.
+
+### Adding HTML content to my awe app
+Learn about the key types of HTML content you can add to your awe app, the standard way you should do this and the common CSS styles you should be aware of. COMING SOON 
+
+### Adding a 'start' page to my awe app
+Learn about how to add an 'start' page that your users will see when they first load your awe app. This is a great place to set the context for what they are about to experience and what they need to do. COMING SOON 
+
+### Referring to assets uploaded to my awe app
+Learn about how you can link to, or reference the different types of assets you have uploaded to the media library within your awe app. COMING SOON 
+
+### Custom branding my awe app
+Learn about the different parts of your awe app that you can change as part of your custom branding using Javascript and CSS. COMING SOON 
+
+### Adding simple object animations to my awe app
+Learn about how to transform and animate one or more objects using Javascript. COMING SOON 
+
+### Adding simple object interactivity to my awe app
+Learn about how to add interactivity to your objects using Javascript. COMING SOON 
+
+### Adding audio to my awe app
+Learn about how to add and manage audio within your awe app using Javascript. COMING SOON 
+
+### Creating menus with objects in my awe app
+Learn about how you can use multiple objects and visibility changes/animations to create multi-object structures like menus. COMING SOON 
+
+### Creating HTML overlay menus in my awe app
+Learn about how you can setup an HTML overlay to create a persistent menu. COMING SOON 
+
+### [Adding a custom 'Scan again' button to my awe app](https://github.com/awe-media/awe.js/wiki/How-To:-Adding-a-custom-scan-again-button-to-my-awe-app)
+Learn about how you can add a scan again button within your views or as a persistent overlay image. [Read more...](https://github.com/awe-media/awe.js/wiki/How-To:-Adding-a-custom-scan-again-button-to-my-awe-app)
+
+### Showing a fullscreen video from a tap on an object in my awe app
+Learn about how you can display a video that fills the browser window when a user taps on an object in your awe app. COMING SOON 
+
+### Events provided by my awe app
+Learn about the common events provided by your awe app for use within your custom Javascript. COMING SOON 
+
+### Working with directions in my awe app
+Learn about how to deal with compass headings and device orientation within custom Javascript for your awe app. COMING SOON 
+
+### Placing content in front of me in my awe app
+Learn about how to use Javascript to place object in front of what the user is looking. COMING SOON 
+
+### Working with locations and active areas in my awe app
+Learn about how to work with geolocation and active area features within your awe app. COMING SOON 
+
+### Adding more sophisticated animations to my awe app
+Learn about how to create more dynamic animations like throwing objects, etc. COMING SOON 
+
+### Adding a score counter to my awe app
+Learn about how to add the HTML, CSS and Javascript needed to add a score counter that tracks different interactions within your awe app. COMING SOON 
+
+### Creating plugins for my awe app
+Learn about how to create your own awe plugins. COMING SOON 
diff --git a/examples/basic/ar.html b/examples/basic/ar.html
deleted file mode 100755
index 3b33bbe..0000000
--- a/examples/basic/ar.html
+++ /dev/null
@@ -1,201 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>AWE basic AR demo</title>
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0" />
-<meta charset="utf-8"/>
-<style type="text/css">
-* {
-	margin: 0;
-	padding: 0;
-}
-#container {
-	position: absolute;
-	left: 0;
-	top: 0;
-	bottom: 0;
-	right: 0;
-	overflow: hidden;
-}
-</style>
-</head>
-<body>
-<div id="container"></div>
-<script type="text/javascript" src="../../js/awe-v8.js"></script>
-<script type="text/javascript" src="../../js/awe-loader.js"></script>
-<script type="text/javascript">
-  window.addEventListener('load', function() {
-    // initialize awe after page loads
-    window.awe.init({
-      // automatically detect the device type
-      device_type: awe.AUTO_DETECT_DEVICE_TYPE,
-      // populate some default settings
-      settings: {
-      	container_id: 'container',
-        fps: 30,
-        default_camera_position: { x:0, y:0, z:0 },
-        default_lights:[
-          {
-            id: 'hemisphere_light',
-            type: 'hemisphere',
-            color: 0xCCCCCC
-          },
-        ],
-      },
-      ready: function() {
-        var d = '?_='+Date.now();
-
-        // load js files based on capability detection then setup the scene if successful
-        awe.util.require([
-          {
-            capabilities: ['webgl','gum'],
-            files: [ 
-              [ '../../js/awe-standard-dependencies.js'+d, '../../js/awe-standard.js'+d ], // core dependencies for this app 
-              ['../../js/plugins/StereoEffect.js'+d, '../../js/plugins/VREffect.js'+d], // dependencies for render effects
-              '../../js/plugins/awe.rendering_effects.js'+d,
-              '../../js/plugins/awe-standard-object_clicked_or_focused.js'+d, // object click/tap handling plugin
-              'awe.gyro.js'+d, // basic gyro handling
-              'awe.mouse.js'+d, // basic mouse handling
-            ],
-            success: function() { 
-              // setup and paint the scene
-			        awe.setup_scene();
-
-  						var click_plugin = awe.plugins.view('object_clicked');
-  						if (click_plugin) {
-    						click_plugin.register();
-    						click_plugin.enable();
-  						}
-  						var gyro_plugin = awe.plugins.view('gyro');
-  						if (gyro_plugin) {
-    						gyro_plugin.enable();
-  						}
-  						var mouse_plugin = awe.plugins.view('gyro');
-  						if (gyro_plugin) {
-    						gyro_plugin.enable();
-  						}
-
-              awe.settings.update({data:{value: 'ar'}, where:{id: 'view_mode'}})
-  						var render_effects_plugin = awe.plugins.view('render_effects');
-  						if (render_effects_plugin) {
-    						render_effects_plugin.enable();
-  						}
-        
-              // setup some code to handle when an object is clicked/tapped
-              window.addEventListener('object_clicked', function(e) { 
-                var p = awe.projections.view(e.detail.projection_id);
-                awe.projections.update({ // rotate clicked object by 180 degrees around x and y axes over 10 seconds
-                  data:{
-                    animation: {
-                      duration: 10,
-                    },
-                    rotation:{ y: p.rotation.y+180, x: p.rotation.x+180 }
-                  },
-                  where:{ id:e.detail.projection_id }
-                });
-              }, false);
-
-			        // add some points of interest (poi) for each of the compass points
-			        awe.pois.add({ id:'north', position: { x:0, y:0, z:200 } });
-			        awe.pois.add({ id:'north_east', position: { x:200, y:0, z:200 } });
-			        awe.pois.add({ id:'east', position: { x:200, y:0, z:0 } });
-			        awe.pois.add({ id:'south_east', position: { x:200, y:0, z:-200 } });
-			        awe.pois.add({ id:'south', position: { x:0, y:0, z:-200 } });
-			        awe.pois.add({ id:'south_west', position: { x:-200, y:0, z:-200 } });
-			        awe.pois.add({ id:'west', position: { x:-200, y:0, z:0 } });
-			        awe.pois.add({ id:'north_west', position: { x:-200, y:0, z:200 } });
-			
-			        // add projections to each of the pois
-			        awe.projections.add({ 
-			          id:'n', 
-			          geometry:{ shape:'cube', x:50, y:50, z:50 }, 
-                rotation:{ x:30, y:30, z:0 },
-			          material:{ 
-			            type: 'phong',
-			            color:0xFF0000, 
-			          },
-			        }, { poi_id: 'north' });
-
-			        awe.projections.add({ 
-			          id:'ne', 
-			          geometry:{ shape:'sphere', radius:10 }, 
-			          material:{ 
-			            type: 'phong',
-			            color:0xCCCCCC, 
-			          },
-			        }, { poi_id: 'north_east' });
-
-			        awe.projections.add({ 
-			          id:'e', 
-			          geometry:{ shape:'cube', x:50, y:50, z:50 }, 
-                rotation:{ x:30, y:30, z:0 },
-			          material:{ 
-			            type: 'phong',
-			            color:0x00FF00, 
-			          },
-			        }, { poi_id: 'east' });
-
-			        awe.projections.add({ 
-			          id:'se', 
-			          geometry:{ shape:'sphere', radius:10 }, 
-			          material:{ 
-			            type: 'phong',
-			            color:0xCCCCCC, 
-			          },
-			        }, { poi_id: 'south_east' });
-
-			        awe.projections.add({ 
-			          id:'s', 
-			          geometry:{ shape:'cube', x:50, y:50, z:50 }, 
-                rotation:{ x:30, y:30, z:0 },
-			          material:{ 
-			            type: 'phong',
-			            color:0xFFFFFF, 
-			          },
-			        }, { poi_id: 'south' });
-
-			        awe.projections.add({ 
-			          id:'sw', 
-			          geometry:{ shape:'sphere', radius:10 }, 
-			          material:{ 
-			            type: 'phong',
-			            color:0xCCCCCC, 
-			          },
-			        }, { poi_id: 'south_west' });
-
-			        awe.projections.add({ 
-			          id:'w', 
-			          geometry:{ shape:'cube', x:50, y:50, z:50 }, 
-                rotation:{ x:30, y:30, z:0 },
-			          material:{ 
-			            type: 'phong',
-			            color:0x0000FF, 
-			          },
-			        }, { poi_id: 'west' });
-
-			        awe.projections.add({ 
-			          id:'nw', 
-			          geometry:{ shape:'sphere', radius:10 }, 
-			          material:{ 
-			            type: 'phong',
-			            color:0xCCCCCC, 
-			          },
-			        }, { poi_id: 'north_west' });
-			
-            },
-          },
-          { // else create a fallback
-            capabilities: [],
-            files: [],
-            success: function() { 
-              document.body.innerHTML = '<p>This demo currently requires a standards compliant mobile browser.';
-              return;
-            },
-          },
-        ]);
-      }
-    });
-  });
-</script>
-</body>
-</html>
diff --git a/examples/basic/awe.gyro.js b/examples/basic/awe.gyro.js
deleted file mode 100644
index 8bee8ca..0000000
--- a/examples/basic/awe.gyro.js
+++ /dev/null
@@ -1,83 +0,0 @@
-;(function(awe) {
-  var device_orientation_data,
-    current_screen_orientation = window.orientation;
-
-  var last_update = performance.now();
-  var enabled = false;
-  var zoom = 700;
-  var zoom_delta = 0;
-  var ready = false;
-  var gyro_mode = 'point'; // none|point|sphere
-  function setup(){
-    ready = true;
-  }
-  
-  awe.plugins.add([{
-    id: 'gyro',
-    capabilities: ['gyro'],
-    auto_register: true,
-    register: function(plugin_data){
-      awe.events.add([
-        {
-          id: 'update_pov',
-          register: function(handler) {
-            window.addEventListener('tick', handler, false);
-          },
-          unregister: function(handler){
-            window.removeEventListener('tick', handler, false);
-          },
-          handler: function(e) {
-            if (!ready) {
-              setup();
-            }
-            if (device_orientation_data && enabled && gyro_mode != 'none') {
-              awe.util.update_pov_quaternion( device_orientation_data, current_screen_orientation, zoom, zoom_delta, last_update, gyro_mode );
-            }
-          }
-        },
-        {
-          id: 'gyro_screenorientation',
-          register: function(handler) {
-            current_screen_orientation = window.orientation;
-            window.addEventListener('orientationchange', handler, false);
-          },
-          unregister: function(handler){
-            window.removeEventListener('orientationchange', handler, false);
-          },
-          handler: function(e) {
-            current_screen_orientation = window.orientation || 0;
-          }
-        },
-        {
-          id: 'deviceorientation',
-          register: function(handler) {
-            window.addEventListener('deviceorientation', handler, false);
-          },
-          unregister: function(handler){
-            window.removeEventListener('deviceorientation', handler, false);
-          },
-          handler: function(e) {
-            device_orientation_data = {
-              alpha: e.alpha,
-              beta: e.beta,
-              gamma: e.gamma
-            };
-          }
-        }
-      ]);
-    },
-    unregister: function(plugin_data){
-      awe.events.delete('update_pov');
-      awe.events.delete('gyro_screenorientation');
-      awe.events.delete('deviceorientation');
-    },
-    enable: function(){
-      console.log('enable gyro')
-      enabled = true;
-    },
-    disable: function(){
-      console.log('disable gyro')
-      enabled = false;
-    },
-  }]);
-})(window.awe);
diff --git a/examples/basic/awe.mouse.js b/examples/basic/awe.mouse.js
deleted file mode 100644
index 943ecaa..0000000
--- a/examples/basic/awe.mouse.js
+++ /dev/null
@@ -1,145 +0,0 @@
-;(function(awe){
-  var enabled = false;
-  var zoom = 700;
-  var zoom_delta = 0;
-  var current_screen_orientation = window.orientation;
-  var last_update = performance.now();
-  var mouse_ready = false;
-  var mouse_mode = 'point'; // none|point|sphere
-  var ignore_click = false;
-  var setup_mouse = function(){
-    if (mouse_ready) { return; }
-    
-    var mouse_position_data = {
-      alpha: 0,
-      beta: 90,
-      gamma: 0.01 // fixed, non-zero
-    };
-    var alpha = mouse_position_data.alpha; // ~ horizontal axis
-    var beta = mouse_position_data.beta; // ~ vertical axis
-    var gamma = mouse_position_data.gamma; // fixed
-    
-    try {
-      var canvas = awe.renderer().get_canvas();
-      var mousedown = false;
-      var horizontal_range = 360; // degrees
-      var vertical_range = 180;
-      var canvas_width = canvas.clientWidth;
-      var canvas_height = canvas.clientHeight;
-      var horizontal_ratio, vertical_ratio;
-      var pov = awe.pov();
-      
-      var initial_x, initial_y, delta_x, delta_y, last_x, last_y;
-      var last_delta = 2;
-      
-      var max_vertical_rotation = 90;
-      var min_vertical_rotation = -90;
-      
-      awe.events.add({
-        id: 'live_view_pov_sensors',
-        register: function(handler){
-          canvas.addEventListener('mousedown', mousedown_handler);
-          canvas.addEventListener('mousemove', mousemove_handler);
-          canvas.addEventListener('mouseup', mouseup_handler);
-          canvas.addEventListener('mouseleave', mouseup_handler);
-          canvas.addEventListener('wheel', wheel_handler);
-        },
-        unregister: function(handler){
-          canvas.removeEventListener('mousedown', mousedown_handler);
-          canvas.removeEventListener('mousemove', mousemove_handler);
-          canvas.removeEventListener('mouseup', mouseup_handler);
-          canvas.removeEventListener('mouseleave', mouseup_handler);
-          canvas.removeEventListener('wheel', wheel_handler);
-        },
-        handler: function(){}
-      });
-      mouse_ready = true;
-
-      function mousedown_handler(e){
-        if ((awe.util.get_settings('paused_interactions'))['paused_interactions']) { return }
-        mousedown = true;
-        if (mouse_mode == 'point') {
-          initial_x = e.clientX;
-          initial_y = e.clientY;
-          last_x = initial_x;
-          last_y = initial_y;
-          canvas_width = canvas.clientWidth;
-          canvas_height = canvas.clientHeight;
-          
-          horizontal_ratio = horizontal_range / canvas_width;
-          vertical_ratio = vertical_range / canvas_height;
-          
-        }
-      }
-      function mouseup_handler(e){
-        if ((awe.util.get_settings('paused_interactions'))['paused_interactions']) { return }
-        
-        mousedown = false;
-        if (mouse_mode == 'point') {
-          alpha = mouse_position_data.alpha;
-          beta = mouse_position_data.beta;
-        }
-      }
-      function mousemove_handler(e){
-        if ((awe.util.get_settings('paused_interactions'))['paused_interactions']) { return }
-
-        if (mouse_mode == 'point') {
-        
-          if (mousedown
-              && (e.clientX <= last_x-last_delta || e.clientX >= last_x+last_delta
-                  || e.clientY <= last_y-last_delta || e.clientY >= last_y+last_delta)
-            ) {
-            e.preventDefault();
-            e.stopPropagation();
-            var position = {},
-              rotation = {};
-        
-            delta_x = initial_x - e.clientX;
-            delta_y = initial_y - e.clientY;
-            
-            mouse_position_data.gamma = gamma;
-            mouse_position_data.alpha = (alpha - delta_x * horizontal_ratio) % 360;
-            mouse_position_data.beta = Math.min(180, Math.max(0, beta - delta_y * vertical_ratio)); // vertical angle 0 -> 180
-            
-            awe.util.update_pov_quaternion( mouse_position_data, current_screen_orientation, zoom, zoom_delta, last_update, mouse_mode );
-            ignore_click = true;
-          }
-          last_x = e.clientX;
-          last_y = e.clientY;
-        }
-      }
-      function wheel_handler(e){
-        // stop the gesture
-        mousedown = false;
-      }
-    }
-    catch(e){
-      console.log(e)
-    }
-  };
-
-  awe.plugins.add([{
-    id: 'mouse',
-    capabilities: [],
-    auto_register: true,
-    register:function(plugin_data) {
-      if (awe.scene_ready) {
-        setup_mouse();
-      } else {
-        window.addEventListener('scene_ready', setup_mouse);
-      }
-    },
-    unregister: function(plugin_data){
-      
-    },
-    enable: function(){
-      console.log('enable mouse')
-      enabled = true;
-    },
-    disable: function(){
-      console.log('disable mouse')
-      enabled = false;
-    },
-  }]);
-
-})(window.awe);
diff --git a/examples/basic/vr.html b/examples/basic/vr.html
deleted file mode 100755
index 399da76..0000000
--- a/examples/basic/vr.html
+++ /dev/null
@@ -1,200 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>AWE basic VR demo</title>
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0" />
-<meta charset="utf-8"/>
-<style type="text/css">
-* {
-	margin: 0;
-	padding: 0;
-}
-#container {
-	position: absolute;
-	left: 0;
-	top: 0;
-	bottom: 0;
-	right: 0;
-	overflow: hidden;
-}
-</style>
-</head>
-<body>
-<div id="container"></div>
-<script type="text/javascript" src="../../js/awe-v8.js"></script>
-<script type="text/javascript" src="../../js/awe-loader.js"></script>
-<script type="text/javascript">
-  window.addEventListener('load', function() {
-    // initialize awe after page loads
-    window.awe.init({
-      // automatically detect the device type
-      device_type: awe.AUTO_DETECT_DEVICE_TYPE,
-      // populate some default settings
-      settings: {
-      	container_id: 'container',
-        fps: 30,
-        default_camera_position: { x:0, y:0, z:0 },
-        default_lights:[
-          {
-            id: 'hemisphere_light',
-            type: 'hemisphere',
-            color: 0xCCCCCC
-          },
-        ],
-      },
-      ready: function() {
-        var d = '?_='+Date.now();
-
-        // load js files based on capability detection then setup the scene if successful
-        awe.util.require([
-          {
-            capabilities: ['webgl'],
-            files: [ 
-              [ '../../js/awe-standard-dependencies.js'+d, '../../js/awe-standard.js'+d ], // core dependencies for this app 
-              ['../../js/plugins/StereoEffect.js'+d, '../../js/plugins/VREffect.js'+d], // dependencies for render effects
-              '../../js/plugins/awe.rendering_effects.js'+d,
-              '../../js/plugins/awe-standard-object_clicked_or_focused.js'+d, // object click/tap handling plugin
-              'awe.gyro.js'+d, // basic gyro handling
-              'awe.mouse.js'+d, // basic mouse handling
-            ],
-            success: function() { 
-              // setup and paint the scene
-			        awe.setup_scene();
-
-  						var click_plugin = awe.plugins.view('object_clicked');
-  						if (click_plugin) {
-    						click_plugin.register();
-    						click_plugin.enable();
-  						}
-  						var gyro_plugin = awe.plugins.view('gyro');
-  						if (gyro_plugin) {
-    						gyro_plugin.enable();
-  						}
-  						var mouse_plugin = awe.plugins.view('gyro');
-  						if (gyro_plugin) {
-    						gyro_plugin.enable();
-  						}
-
-  						var render_effects_plugin = awe.plugins.view('render_effects');
-  						if (render_effects_plugin) {
-    						render_effects_plugin.enable();
-  						}
-        
-              // setup some code to handle when an object is clicked/tapped
-              window.addEventListener('object_clicked', function(e) { 
-                var p = awe.projections.view(e.detail.projection_id);
-                awe.projections.update({ // rotate clicked object by 180 degrees around x and y axes over 10 seconds
-                  data:{
-                    animation: {
-                      duration: 10,
-                    },
-                    rotation:{ y: p.rotation.y+180, x: p.rotation.x+180 }
-                  },
-                  where:{ id:e.detail.projection_id }
-                });
-              }, false);
-
-			        // add some points of interest (poi) for each of the compass points
-			        awe.pois.add({ id:'north', position: { x:0, y:0, z:200 } });
-			        awe.pois.add({ id:'north_east', position: { x:200, y:0, z:200 } });
-			        awe.pois.add({ id:'east', position: { x:200, y:0, z:0 } });
-			        awe.pois.add({ id:'south_east', position: { x:200, y:0, z:-200 } });
-			        awe.pois.add({ id:'south', position: { x:0, y:0, z:-200 } });
-			        awe.pois.add({ id:'south_west', position: { x:-200, y:0, z:-200 } });
-			        awe.pois.add({ id:'west', position: { x:-200, y:0, z:0 } });
-			        awe.pois.add({ id:'north_west', position: { x:-200, y:0, z:200 } });
-			
-			        // add projections to each of the pois
-			        awe.projections.add({ 
-			          id:'n', 
-			          geometry:{ shape:'cube', x:50, y:50, z:50 }, 
-                rotation:{ x:30, y:30, z:0 },
-			          material:{ 
-			            type: 'phong',
-			            color:0xFF0000, 
-			          },
-			        }, { poi_id: 'north' });
-
-			        awe.projections.add({ 
-			          id:'ne', 
-			          geometry:{ shape:'sphere', radius:10 }, 
-			          material:{ 
-			            type: 'phong',
-			            color:0xCCCCCC, 
-			          },
-			        }, { poi_id: 'north_east' });
-
-			        awe.projections.add({ 
-			          id:'e', 
-			          geometry:{ shape:'cube', x:50, y:50, z:50 }, 
-                rotation:{ x:30, y:30, z:0 },
-			          material:{ 
-			            type: 'phong',
-			            color:0x00FF00, 
-			          },
-			        }, { poi_id: 'east' });
-
-			        awe.projections.add({ 
-			          id:'se', 
-			          geometry:{ shape:'sphere', radius:10 }, 
-			          material:{ 
-			            type: 'phong',
-			            color:0xCCCCCC, 
-			          },
-			        }, { poi_id: 'south_east' });
-
-			        awe.projections.add({ 
-			          id:'s', 
-			          geometry:{ shape:'cube', x:50, y:50, z:50 }, 
-                rotation:{ x:30, y:30, z:0 },
-			          material:{ 
-			            type: 'phong',
-			            color:0xFFFFFF, 
-			          },
-			        }, { poi_id: 'south' });
-
-			        awe.projections.add({ 
-			          id:'sw', 
-			          geometry:{ shape:'sphere', radius:10 }, 
-			          material:{ 
-			            type: 'phong',
-			            color:0xCCCCCC, 
-			          },
-			        }, { poi_id: 'south_west' });
-
-			        awe.projections.add({ 
-			          id:'w', 
-			          geometry:{ shape:'cube', x:50, y:50, z:50 }, 
-                rotation:{ x:30, y:30, z:0 },
-			          material:{ 
-			            type: 'phong',
-			            color:0x0000FF, 
-			          },
-			        }, { poi_id: 'west' });
-
-			        awe.projections.add({ 
-			          id:'nw', 
-			          geometry:{ shape:'sphere', radius:10 }, 
-			          material:{ 
-			            type: 'phong',
-			            color:0xCCCCCC, 
-			          },
-			        }, { poi_id: 'north_west' });
-			
-            },
-          },
-          { // else create a fallback
-            capabilities: [],
-            files: [],
-            success: function() { 
-              document.body.innerHTML = '<p>This demo currently requires a standards compliant mobile browser.';
-              return;
-            },
-          },
-        ]);
-      }
-    });
-  });
-</script>
-</body>
-</html>
diff --git a/examples/marker_ar/64.png b/examples/marker_ar/64.png
deleted file mode 100755
index ece4eaf5c437451116db04215ef918bc6861af09..0000000000000000000000000000000000000000
GIT binary patch
diff --git a/examples/marker_ar/awe-jsartoolkit-dependencies.js b/examples/marker_ar/awe-jsartoolkit-dependencies.js
deleted file mode 100755
index 08aeea4..0000000
--- a/examples/marker_ar/awe-jsartoolkit-dependencies.js
+++ /dev/null
@@ -1,11646 +0,0 @@
-/*
-  NOTE: We have combined the minimum collection of required js libs awe depends
-        upon to make it easy for you to get started using JSARToolkit
-
-        Please see the JSARToolkit github repos for the original source files 
-        https://github.com/kig/JSARToolKit
-*/
-
-// BEGIN FILE: NyAs3Utils.js 
-/*
- * JSARToolkit
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- *   Hirokazu Kato
- *   Mark Billinghurst
- *   HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * And the NyARToolkitAS3 ARToolKit class library.
- *   Copyright (C)2010 Ryo Iizuka
- *
- * JSARToolkit is a JavaScript port of NyARToolkitAS3.
- *   Copyright (C)2010 Ilmari Heikkinen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- * 
- * For further information please contact.
- *   ilmari.heikkinen@gmail.com
- *
- */
-
-if (!window.console) console = { log : function(){} };
-
-ASVector = function(elements) {
-  elements = elements || 0;
-  if (elements.length) {
-    this.length = elements.length;
-    for (var i=0; i<elements.length; i++)
-      this[i] = elements[i];
-  } else {
-    this.length = elements;
-    for (var i=0; i<elements; i++)
-      this[i] = 0;
-  }
-}
-ASVector.prototype = {};
-ASVector.prototype.set = function(idx, val) {
-  if (idx.length)
-    ASVector.call(this, idx);
-  else
-    this[idx] = val;
-}
-
-if (typeof Float32Array == 'undefined') {
-  FloatVector = ASVector;
-  IntVector = ASVector;
-  UintVector = ASVector;
-} else {
-  FloatVector = Float32Array;
-  IntVector = Int32Array;
-  UintVector = Uint32Array;
-}
-
-toInt = Math.floor;
-
-Object.extend = function(dst, src) {
-  for (var i in src) {
-    try{ dst[i] = src[i]; } catch(e) {}
-  }
-  return dst;
-}
-
-toArray = function(obj) {
-  var a = new Array(obj.length);
-  for (var i=0; i<obj.length; i++)
-    a[i] = obj[i];
-  return a;
-}
-
-Klass = (function() {
-  var c = function() {
-    if (this.initialize)
-      this.initialize.apply(this, arguments);
-  }
-  c.ancestors = toArray(arguments);
-  c.prototype = {};
-  for(var i = 0; i<arguments.length; i++) {
-    var a = arguments[i];
-    if (a.prototype) {
-      Object.extend(c.prototype, a.prototype);
-    } else {
-      Object.extend(c.prototype, a);
-    }
-  }
-  Object.extend(c, c.prototype);
-  return c;
-})
-
-Object.asCopy = function(obj) {
-  if (typeof obj != 'object') {
-    return obj;
-  } else if (obj instanceof FloatVector) {
-    var v = new FloatVector(obj.length);
-    for (var i=0; i<v.length; i++)
-      v[i] = obj[i];
-    return v;
-  } else if (obj instanceof IntVector) {
-    var v = new IntVector(obj.length);
-    for (var i=0; i<v.length; i++)
-      v[i] = obj[i];
-    return v;
-  } else if (obj instanceof UintVector) {
-    var v = new UintVector(obj.length);
-    for (var i=0; i<v.length; i++)
-      v[i] = obj[i];
-    return v;
-  } else if (obj instanceof Array) {
-    return obj.map(Object.asCopy);
-  } else {
-    var newObj = {};
-    for (var i in obj) {
-      var v = obj[i];
-      if (typeof v == 'object') {
-        v = Object.asCopy(v);
-      }
-      newObj[i] = v;
-    }
-    return newObj;
-  }
-}
-
-ASKlass = (function(name) {
-  var c = function() {
-    var cc = this.__copyObjects__;
-    for (var i=0; i<cc.length; i++)
-      this[cc[i]] = Object.asCopy(this[cc[i]])
-    if (this.initialize)
-      this.initialize.apply(this, arguments);
-  }
-  c.ancestors = toArray(arguments).slice(1);
-  c.prototype = {};
-  for(var i = 1; i<arguments.length; i++) {
-    var a = arguments[i];
-    if (a.prototype) {
-      Object.extend(c.prototype, a.prototype);
-    } else {
-      Object.extend(c.prototype, a);
-    }
-  }
-  c.prototype.className = name;
-  c.prototype.initialize = c.prototype[name];
-  c.prototype.__copyObjects__ = [];
-  for (var i in c.prototype) {
-    var v = c.prototype[i];
-    if (i != '__copyObjects__') {
-      if (typeof v == 'object') {
-        c.prototype.__copyObjects__.push(i);
-      }
-    }
-  }
-  Object.extend(c, c.prototype);
-  return c;
-})
-
-
-/**
- * A partial implementation of the ActionScript3 BitmapData class.
- * See: http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/display/BitmapData.html
- */
-BitmapData = Klass({
-  initialize : function(i_width, i_height, transparent, fill) {
-    this.width = i_width;
-    this.height = i_height;
-    this.transparent = (transparent == null ? true : transparent);
-    this.fill = (fill == null ? 0xffffffff : fill);
-    this.data = new UintVector(i_width*i_height);
-    for (var i=0; i<this.data.length; i++) {
-      this.data[i] = fill;
-    }
-    this.rect = new Rectangle(0,0,this.width, this.height);
-  },
-  fillRect : function(rect, value) {
-    var stride = this.width;
-    var y = Math.clamp(rect.y,0,this.height)*stride
-      , y2 = Math.clamp(rect.y+rect.height,0,this.height)*stride
-      , x = Math.clamp(rect.x,0,this.width)
-      , x2 = Math.clamp(rect.x+rect.width,0,this.width);
-    var d = this.data;
-    for (var y1=y;y1<y2; y1+=stride)
-      for (var x1=x;x1<x2; x1++)
-        d[y1+x1] = value;
-  },
-  getPixel32 : function(x,y) {
-    return this.data[y*this.width + x];
-  },
-  setPixel32 : function(x,y,v) {
-    return this.data[y*this.width + x] = v;
-  },
-  getPixel : function(x,y) {
-    return this.data[y*this.width + x] & 0x00ffffff;
-  },
-  setPixel : function(x,y,v) {
-    return this.data[y*this.width + x] = v | (this.data[y*this.width + x] & 0xff000000);
-  },
-  getWidth : function () { return this.width; },
-  getHeight : function () { return this.height; },
-  copyPixels : function(source, rect, offset) {
-    var tstride = this.width;
-    var stride = source.width;
-    var d = source.data;
-    var td = this.data;
-    var ty = Math.clamp(offset.y,0,this.height)*tstride
-      , ty2 = Math.clamp(offset.y+rect.height,0,this.height)*tstride
-      , tx = Math.clamp(offset.x,0,this.width)
-      , tx2 = Math.clamp(offset.x+rect.width,0,this.width);
-    var y = Math.clamp(rect.y,0,source.height)*stride
-      , y2 = Math.clamp(rect.y+rect.height,0,source.height)*stride
-      , x = Math.clamp(rect.x,0,source.width)
-      , x2 = Math.clamp(rect.x+rect.width,0,source.width);
-    for (var y1=y,ty1=ty; y1<y2 && ty1<ty2; y1+=stride,ty1+=tstride)
-      for (var x1=x,tx1=tx; x1<x2 && tx1<tx2; x1++,tx1++)
-        td[ty1+tx1] = d[y1+x1];
-  },
-  getColorBoundsRect : function(mask, color, findColor) {
-    if (findColor) {
-      return this.getColorBoundsRect_true(mask, color);
-    } else {
-      return this.getColorBoundsRect_false(mask, color);
-    }
-  },
-  getColorBoundsRect_true : function(mask, color) {
-    var minX=this.width, minY=this.height, maxX=0, maxY=0;
-    var w = this.width; h=this.height;
-    var d = this.data;
-    var m = 0, off = 0;
-    minYfor: for (var y=0; y<h; y++) {
-      off = y*w-1;
-      for (var x=0; x<w; x++) {
-        m = (d[++off] & mask) - color;
-        if (!m) {
-          minX = maxX = x;
-          minY = maxY = y;
-          break minYfor;
-        }
-      }
-    }
-    maxYfor: for (var y=h-1; y>minY; y--) {
-      off = y*w-1;
-      for (var x=0; x<w; x++) {
-        m = (d[++off] & mask) - color;
-        if (!m) {
-          if (x < minX) minX = x;
-          if (x > maxX) maxX = x;
-          maxY = y;
-          break maxYfor;
-        }
-      }
-    }
-    for (var y=minY; y<=maxY; y++) {
-      off = y*w-1;
-      for (var x=0; x<minX; x++) {
-        m = (d[++off] & mask) - color;
-        if (!m) {
-          minX = x;
-          break;
-        }
-      }
-      off = y*w+w;
-      for (var x=w-1; x>maxX; x--) {
-        m = (d[--off] & mask) - color;
-        if (!m) {
-          maxX = x;
-          break;
-        }
-      }
-    }
-    return new Rectangle(minX, minY, Math.max(0,maxX-minX), Math.max(0,maxY-minY));
-  },
-  getColorBoundsRect_false : function(mask, color) {
-    var minX=this.width, minY=this.height, maxX=0, maxY=0;
-    var w = this.width; h=this.height;
-    var d = this.data;
-    minYfor: for (var y=0; y<h; y++) {
-      for (var x=0; x<w; x++) {
-        var m = (d[y*w+x] & mask) - color;
-        if (m) {
-          minX = maxX = x;
-          minY = maxY = y;
-          break minYfor;
-        }
-      }
-    }
-    maxYfor: for (var y=h-1; y>minY; y--) {
-      for (var x=0; x<w; x++) {
-        var m = (d[y*w+x] & mask) - color;
-        if (m) {
-          if (x < minX) minX = x;
-          if (x > maxX) maxX = x;
-          maxY = y;
-          break maxYfor;
-        }
-      }
-    }
-    for (var y=minY; y<=maxY; y++) {
-      for (var x=0; x<minX; x++) {
-        var m = (d[y*w+x] & mask) - color;
-        if (m) {
-          minX = x;
-          break;
-        }
-      }
-      for (var x=h-1; x>maxX; x--) {
-        var m = (d[y*w+x] & mask) - color;
-        if (m) {
-          maxX = x;
-          break;
-        }
-      }
-    }
-    return new Rectangle(minX, minY, Math.max(0,maxX-minX), Math.max(0,maxY-minY));
-  },
-  putImageData : function(imageData, x,y, w,h) {
-    w = Math.clamp(w,0,imageData.width), h = Math.clamp(h,0,imageData.height);
-    var stride = this.width;
-    var d = this.data;
-    var td = imageData.data;
-    var y = Math.clamp(y,0,this.height)*stride
-      , y2 = Math.clamp(y+h,0,this.height)*stride
-      , x = Math.clamp(x,0,this.width)
-      , x2 = Math.clamp(x+w,0,this.width);
-    for (var y1=y,ty1=0; y1<y2; y1+=stride,ty1+=imageData.width*4) {
-      for (var x1=x,tx1=0; x1<x2; x1++,tx1+=4) {
-        d[y1+x1] = ( // transform canvas pixel to 32-bit ARGB int
-          (td[ty1+tx1] << 16) |
-          (td[ty1+tx1+1] << 8) |
-          (td[ty1+tx1+2]) |
-          (td[ty1+tx1+3] << 24)
-        );
-      }
-    }
-  },
-  drawCanvas : function(canvas, x,y,w,h) {
-    this.putImageData(canvas.getContext('2d').getImageData(0,0,w,h),x,y,w,h);
-  },
-  drawOnCanvas : function(canvas) {
-    var ctx = canvas.getContext('2d');
-    var id = ctx.getImageData(0,0,this.width,this.height);
-    var stride = this.width;
-    var length = this.height*stride;
-    var d = this.data;
-    var td = id.data;
-    for (var y=0; y<length; y+=stride) {
-      for (var x=0; x<stride; x++) {
-        var base = 4*(y+x);
-        var c = d[y+x];
-        td[base] = (c >> 16) & 0xff;
-        td[++base] = (c >> 8) & 0xff;
-        td[++base] = (c) & 0xff;
-        td[++base] = (c >> 24) & 0xff;
-      }
-    }
-    ctx.putImageData(id, 0,0);
-  },
-  floodFill : function(x, y, nv) {
-    var l=0, x1=0, x2=0, dy=0;
-    var ov=0; /* old pixel value */
-    var stack = [];
-    var w = this.width, h = this.height;
-    var stride = this.width;
-    var data = this.data;
-
-    ov = data[y*stride + x];
-    if (ov==nv || x<0 || x>=w || y<0 || y>=h) return;
-    stack.push([y, x, x, 1]);     /* needed in some cases */
-    stack.push([y+1, x, x, -1]);    /* seed segment (popped 1st) */
-
-    while (stack.length > 0) {
-      /* pop segment off stack and fill a neighboring scan line */
-      var a = stack.pop();
-      y = a[0]+a[3], x1 = a[1], x2 = a[2], dy = a[3];
-      /*
-      * segment of scan line y-dy for x1<=x<=x2 was previously filled,
-      * now explore adjacent pixels in scan line y
-      */
-      for (x=x1; x>=0 && data[y*stride + x]==ov; x--)
-        data[y*stride + x] = nv;
-      if (x<x1) {
-        l = x+1;
-        if (l<x1) stack.push([y, l, x1-1, -dy]);    /* leak on left? */
-        x = x1+1;
-        for (; x<w && data[y*stride + x]==ov; x++)
-          data[y*stride + x] = nv;
-        stack.push([y, l, x-1, dy]);
-        if (x>x2+1) stack.push([y, x2+1, x-1, -dy]);  /* leak on right? */
-      }
-      for (x++; x<=x2 && data[y*stride + x]!=ov; x++)
-        null;
-      l = x;
-      while (x<=x2) {
-        for (; x<w && data[y*stride + x]==ov; x++)
-          data[y*stride + x] = nv;
-        stack.push([y, l, x-1, dy]);
-        if (x>x2+1) stack.push([y, x2+1, x-1, -dy]);  /* leak on right? */
-        for (x++; x<=x2 && data[y*stride + x]!=ov; x++)
-          null;
-        l = x;
-      }
-    }
-  }
-})
-
-Rectangle = Klass({
-  initialize : function(x,y,w,h){
-    this.x = x; this.y = y;
-    this.top = y; this.left = x;
-    this.bottom = y+h; this.right = x+w;
-    this.width = w; this.height = h;
-    this.updateCalc();
-  },
-  updateCalc : function() {
-    this.top = this.y;
-    this.left = this.x;
-    this.bottom = this.y+this.height;
-    this.right = this.x+this.width;
-  },
-  clone : function() {
-    return new Rectangle(this.x, this.y, this.width, this.height);
-  },
-  inflate : function(dx,dy) {
-    this.x -= dx;
-    this.y -= dy;
-    this.width += 2 * dx;
-    this.height += 2 * dy;
-    this.updateCalc();
-  },
-  isEmpty : function() {
-    return (this.width <= 0 && this.height <= 0)
-  }
-})
-
-/**
-  * The Exception object used by NyARToolkit.
-  */
-NyARException = Klass(Error,
-{
-  initialize : function(m)
-  {
-    Error.call(this,m);
-  },
-  trap : function(m)
-  {
-    throw new NyARException("trap:" + m);
-  },
-
-  notImplement : function()
-  {
-    throw new NyARException("Not Implement!");
-  }
-})
-
-NyAS3Const_Inherited = Klass({
-})
-
-NyAS3Utils = Klass(
-{
-  assert : function(e, mess)
-  {
-    if(!e){throw new Error("NyAS3Utils.assert:"+mess!=null?mess:"");}
-  }
-})
-
-NyARVec = Klass(
-{
-  clm : null,
-  v : null,
-
-  initialize : function(i_clm)
-  {
-    this.v = new FloatVector(i_clm);
-    this.clm = i_clm;
-  },
-
-  getClm : function()
-  {
-    return this.clm;
-  },
-  getArray : function()
-  {
-    return this.v;
-  }
-})
-
-/**
-  * ARMat構造体に対応するクラス typedef struct { double *m; int row; int clm; }ARMat;
-  *
-  */
-NyARMat = Klass(
-{
-  /**
-    * 配列サイズと行列サイズは必ずしも一致しないことに注意 返された配列のサイズを行列の大きさとして使わないこと！
-    *
-    */
-  m : null,
-  __matrixSelfInv_nos : null,
-
-  clm : null,
-  row : null,
-
-  initialize : function(i_row,i_clm)
-  {
-    this.m = new Array(i_row);
-    for (var i=0; i<i_row; i++) {
-      this.m[i] = new FloatVector(i_clm);
-      for (var j=0; j<i_clm; j++)
-        this.m[i][j] = 0.0;
-    }
-    this.__matrixSelfInv_nos=new FloatVector(i_row);
-    this.clm = i_clm;
-    this.row = i_row;
-    return;
-  }
-  /**
-    * 行列の列数を返します。
-    * @return
-    */
-  ,getClm : function()
-  {
-    return this.clm;
-  }
-  /**
-    * 行列の行数を返します。
-    * @return
-    */
-  ,getRow : function()
-  {
-    return this.row;
-  }
-  ,getArray : function()
-  {
-    return this.m;
-  }
-  /**
-    * 逆行列を計算して、thisへ格納します。
-    * @throws NyARException
-    */
-  ,matrixSelfInv : function()
-  {
-    var ap = this.m;
-    var dimen = this.row;
-    var dimen_1 = dimen - 1;
-    var ap_n, ap_ip, ap_i;// wap;
-    var j, ip, nwork;
-    var nos = this.__matrixSelfInv_nos;//ワーク変数
-    // double epsl;
-    var p, pbuf, work;
-
-    /* check size */
-    switch (dimen) {
-    case 0:
-      throw new NyARException();
-    case 1:
-      ap[0][0] = 1.0 / ap[0][0];// *ap = 1.0 / (*ap);
-      return true;/* 1 dimension */
-    }
-    var n;
-    for (n = 0; n < dimen; n++) {
-      nos[n] = n;
-    }
-
-    /*
-      * nyatla memo ipが定まらないで計算が行われる場合があるので挿入。 ループ内で0初期化していいかが判らない。
-      */
-    ip = 0;
-    // For順変更禁止
-    for (n = 0; n < dimen; n++) {
-      ap_n = ap[n];// wcp = ap + n * rowa;
-      p = 0.0;
-      for (var i = n; i < dimen; i++) {
-        if (p < (pbuf = Math.abs(ap[i][0]))) {
-          p = pbuf;
-          ip = i;
-        }
-      }
-      // if (p <= matrixSelfInv_epsl){
-      if (p == 0.0) {
-        return false;
-        // throw new NyARException();
-      }
-
-      nwork = nos[ip];
-      nos[ip] = nos[n];
-      nos[n] = nwork;
-
-      ap_ip = ap[ip];
-      for (j = 0; j < dimen; j++) {// for(j = 0, wap = ap + ip * rowa,
-                      // wbp = wcp; j < dimen ; j++) {
-        work = ap_ip[j]; // work = *wap;
-        ap_ip[j] = ap_n[j];
-        ap_n[j] = work;
-      }
-
-      work = ap_n[0];
-      for (j = 0; j < dimen_1; j++) {
-        ap_n[j] = ap_n[j + 1] / work;// *wap = *(wap + 1) / work;
-      }
-      ap_n[j] = 1.0 / work;// *wap = 1.0 / work;
-      for (i = 0; i < dimen; i++) {
-        if (i != n) {
-          ap_i = ap[i];// wap = ap + i * rowa;
-          work = ap_i[0];
-          for (j = 0; j < dimen_1; j++) {// for(j = 1, wbp = wcp,work = *wap;j < dimen ;j++, wap++, wbp++)
-            ap_i[j] = ap_i[j + 1] - work * ap_n[j];// wap = *(wap +1) - work *(*wbp);
-          }
-          ap_i[j] = -work * ap_n[j];// *wap = -work * (*wbp);
-        }
-      }
-    }
-
-    for (n = 0; n < dimen; n++) {
-      for (j = n; j < dimen; j++) {
-        if (nos[j] == n) {
-          break;
-        }
-      }
-      nos[j] = nos[n];
-      for (i = 0; i < dimen; i++) {
-        ap_i = ap[i];
-        work = ap_i[j];// work = *wap;
-        ap_i[j] = ap_i[n];// *wap = *wbp;
-        ap_i[n] = work;// *wbp = work;
-      }
-    }
-    return true;
-  }
-})
-
-ArrayUtils = ASKlass('ArrayUtils',
-{
-  create2dInt : function(height, width)
-  {
-    var r = new Array(height);
-    for (var i = 0; i < height; i++){
-      r[i] = new IntVector(width);
-    }
-    return r;
-  }
-  ,create2dNumber : function(height, width)
-  {
-    var r = new Array(height);
-    for (var i = 0; i < height; i++){
-      r[i] = new FloatVector(width);
-    }
-    return r;
-  }
-  ,copyInt : function(src, srcPos, dest, destPos, length) {
-    for (var i = 0; i < length; i++) {
-      dest[destPos + i] = src[srcPos + i];
-    }
-  }
-})
-// END FILE: NyAs3Utils.js 
-
-// BEGIN FILE: 
-/*
- * PROJECT: FLARToolKit
- * --------------------------------------------------------------------------------
- * This work is based on the NyARToolKit developed by
- *   R.Iizuka (nyatla)
- * http://nyatla.jp/nyatoolkit/
- *
- * The FLARToolKit is ActionScript 3.0 version ARToolkit class library.
- * Copyright (C)2008 Saqoosha
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this framework; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * For further information please contact.
- *  http://www.libspark.org/wiki/saqoosha/FLARToolKit
- *  <saq(at)saqoosha.net>
- *
- */
-ArrayUtil = ASKlass('ArrayUtil', {
-  createJaggedArray : function(len) {
-    var arr = new Array(len);
-    var args = toArray(arguments).slice(1);
-    while (len--) {
-      arr[len] = args.length ? this.createJaggedArray.apply(null, args) : 0;
-    }
-    return arr;
-  }
-  ,create2d : function(height, width) {
-    return this.createJaggedArray(height, width);
-  }
-  ,create3d : function(depth, height, width) {
-    return this.createJaggedArray(depth, height, width);
-  }
-  ,copy : function(src, srcPos, dest, destPos, length) {
-    for (var i = 0; i < length; i++) {
-      dest[destPos + i] = src[srcPos + i];
-    }
-  }
-})
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * PROJECT: FLARToolKit
- * --------------------------------------------------------------------------------
- * This work is based on the NyARToolKit developed by
- *   R.Iizuka (nyatla)
- * http://nyatla.jp/nyatoolkit/
- *
- * The FLARToolKit is ActionScript 3.0 version ARToolkit class library.
- * Copyright (C)2008 Saqoosha
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  http://www.libspark.org/wiki/saqoosha/FLARToolKit
- *  <saq(at)saqoosha.net>
- *
- */
-FLARMat = NyARMat;
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * PROJECT: FLARToolKit
- * --------------------------------------------------------------------------------
- * This work is based on the NyARToolKit developed by
- *   R.Iizuka (nyatla)
- * http://nyatla.jp/nyatoolkit/
- *
- * The FLARToolKit is ActionScript 3.0 version ARToolkit class library.
- * Copyright (C)2008 Saqoosha
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  http://www.libspark.org/wiki/saqoosha/FLARToolKit
- *  <saq(at)saqoosha.net>
- *
- */
-FLARRgbPixelReader_BitmapData = ASKlass('FLARRgbPixelReader_BitmapData',
-{
-  _ref_bitmap : null
-  ,FLARRgbPixelReader_BitmapData : function(i_buffer)
-  {
-    this._ref_bitmap = i_buffer;
-  }
-  ,getPixel : function(i_x, i_y, o_rgb)
-  {
-    var c = this._ref_bitmap.getPixel(i_x, i_y);
-    o_rgb[0] = (c >> 16) & 0xff;// R
-    o_rgb[1] = (c >> 8) & 0xff;// G
-    o_rgb[2] = c & 0xff;// B
-    return;
-  }
-  ,getPixelSet : function(i_x, i_y, i_num, o_rgb)
-  {
-    var bmp = this._ref_bitmap;
-    var c;
-    var i;
-    for (i = 0; i < i_num; i++) {
-      c = bmp.getPixel(i_x[i], i_y[i]);
-      o_rgb[i*3+0] = (c >> 16) & 0xff;
-      o_rgb[i*3+1] = (c >> 8) & 0xff;
-      o_rgb[i*3+2] = c & 0xff;
-    }
-  }
-  ,setPixel : function(i_x, i_y, i_rgb)
-  {
-    NyARException.notImplement();
-  }
-  ,setPixels : function(i_x, i_y, i_num, i_intrgb)
-  {
-    NyARException.notImplement();
-  }
-  ,switchBuffer : function(i_ref_buffer)
-  {
-    NyARException.notImplement();
-  }
-})
-FLARGrayPixelReader_BitmapData = ASKlass('FLARGrayPixelReader_BitmapData',
-{
-  _ref_bitmap : null
-  ,FLARGrayPixelReader_BitmapData : function(i_buffer)
-  {
-    this._ref_bitmap = i_buffer;
-  }
-  ,getPixel : function(i_x, i_y, i_num, o_gray)
-  {
-    NyARException.notImplement();
-    var w = this._ref_bitmap.getWidth();
-    var d = this._ref_bitmap.getBuffer();
-    o_gray[0] = o_gray[1] = o_gray[2] = ~d(i_x + w*i_y) & 0xff;
-  }
-  ,getPixelSet : function(i_x, i_y, i_num, o_gray)
-  {
-    var w = this._ref_bitmap.getWidth();
-    var d = this._ref_bitmap.data;
-    for (var i = 0; i < i_num; i++) {
-      o_gray[i] = ~d[i_x[i] + w*i_y[i]] & 0xff;
-    }
-  }
-  ,setPixel : function(i_x, i_y, i_rgb)
-  {
-    NyARException.notImplement();
-  }
-  ,setPixels : function(i_x, i_y, i_num, i_intrgb)
-  {
-    NyARException.notImplement();
-  }
-  ,switchBuffer : function(i_ref_buffer)
-  {
-    NyARException.notImplement();
-  }
-})
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * JSARToolkit
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- *   Hirokazu Kato
- *   Mark Billinghurst
- *   HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * And the NyARToolkitAS3 ARToolKit class library.
- *   Copyright (C)2010 Ryo Iizuka
- *
- * JSARToolkit is a JavaScript port of NyARToolkitAS3.
- *   Copyright (C)2010 Ilmari Heikkinen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  ilmari.heikkinen@gmail.com
- *
- */
-INyARHistogramAnalyzer_Threshold = ASKlass('INyARHistogramAnalyzer_Threshold',
-{
-  getThreshold : function(i_histgram){}
-})
-NyARHistogramAnalyzer_SlidePTile = ASKlass('NyARHistogramAnalyzer_SlidePTile', INyARHistogramAnalyzer_Threshold,
-{
-  _persentage : 0,
-  NyARHistogramAnalyzer_SlidePTile : function(i_persentage)
-  {
-    NyAS3Utils.assert (0 <= i_persentage && i_persentage <= 50);
-    //初期化
-    this._persentage=i_persentage;
-  }
-  ,getThreshold : function(i_histgram)
-  {
-    //総ピクセル数を計算
-    var n=i_histgram.length;
-    var sum_of_pixel=i_histgram.total_of_data;
-    var hist=i_histgram.data;
-    // 閾値ピクセル数確定
-    var th_pixcels = sum_of_pixel * this._persentage / 100;
-    var th_wk;
-    var th_w, th_b;
-    // 黒点基準
-    th_wk = th_pixcels;
-    for (th_b = 0; th_b < n-2; th_b++) {
-      th_wk -= hist[th_b];
-      if (th_wk <= 0) {
-        break;
-      }
-    }
-    // 白点基準
-    th_wk = th_pixcels;
-    for (th_w = n-1; th_w > 1; th_w--) {
-      th_wk -= hist[th_w];
-      if (th_wk <= 0) {
-        break;
-      }
-    }
-    // 閾値の保存
-    return (th_w + th_b) / 2;
-  }
-})
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * JSARToolkit
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- *   Hirokazu Kato
- *   Mark Billinghurst
- *   HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * And the NyARToolkitAS3 ARToolKit class library.
- *   Copyright (C)2010 Ryo Iizuka
- *
- * JSARToolkit is a JavaScript port of NyARToolkitAS3.
- *   Copyright (C)2010 Ilmari Heikkinen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  ilmari.heikkinen@gmail.com
- *
- */
-INyARPca2d = ASKlass('INyARPca2d',
-{
-  /**
-   * 通常のPCA
-   * @param i_v1
-   * @param i_v2
-   * @param i_start
-   * @param i_number_of_point
-   * @param o_evec
-   * 要素2の変数を指定してください。
-   * @param o_ev
-   * 要素2の変数を指定してください。
-   * @param o_mean
-   * @throws NyARException
-   */
-  pca : function(i_v1, i_v2, i_number_of_point, o_evec, o_ev, o_mean){}
-})
-NyARPca2d_MatrixPCA_O2 = ASKlass('NyARPca2d_MatrixPCA_O2', INyARPca2d,
-{
-  PCA_EPS : 1e-6, // #define EPS 1e-6
-  PCA_MAX_ITER : 100, // #define MAX_ITER 100
-  PCA_VZERO : 1e-16, // #define VZERO 1e-16
-  /**
-   * static int QRM( ARMat *a, ARVec *dv )の代替関数
-   *
-   * @param a
-   * @param dv
-   * @throws NyARException
-   */
-  PCA_QRM : function(o_matrix,dv)
-  {
-    var w, t, s, x, y, c;
-    var ev1;
-    var dv_x,dv_y;
-    var mat00,mat01,mat10,mat11;
-    // <this.vecTridiagonalize2d(i_mat, dv, ev);>
-    dv_x = o_matrix.m00;// this.m[dim - 2][dim - 2];// d.v[dim-2]=a.m[dim-2][dim-2];//d->v[dim-2]=a->m[(dim-2)*dim+(dim-2)];
-    ev1 = o_matrix.m01;// this.m[dim - 2][dim - 1];// e.v[dim-2+i_e_start]=a.m[dim-2][dim-1];//e->v[dim-2] = a->m[(dim-2)*dim+(dim-1)];
-    dv_y = o_matrix.m11;// this.m[dim - 1][dim - 1];// d.v[dim-1]=a_array[dim-1][dim-1];//d->v[dim-1] =a->m[(dim-1)*dim+(dim-1)];
-    // 単位行列にする。
-    mat00 = mat11 = 1;
-    mat01 = mat10 = 0;
-    // </this.vecTridiagonalize2d(i_mat, dv, ev);>
-    // int j = 1;
-    // // while(j>0 && fabs(ev->v[j])>EPS*(fabs(dv->v[j-1])+fabs(dv->v[j])))
-    // while (j > 0 && Math.abs(ev1) > PCA_EPS * (Math.abs(dv.x) + Math.abs(dv.y))) {
-    // j--;
-    // }
-    // if (j == 0) {
-    var iter = 0;
-    do {
-      iter++;
-      if (iter > this.PCA_MAX_ITER) {
-        break;
-      }
-      w = (dv_x - dv_y) / 2;// w = (dv->v[h-1] -dv->v[h]) / 2;//ここ？
-      t = ev1 * ev1;// t = ev->v[h] * ev->v[h];
-      s = Math.sqrt(w * w + t);
-      if (w < 0) {
-        s = -s;
-      }
-      x = dv_x - dv_y + t / (w + s);// x = dv->v[j] -dv->v[h] +t/(w+s);
-      y = ev1;// y = ev->v[j+1];
-      if (Math.abs(x) >= Math.abs(y)) {
-        if (Math.abs(x) > this.PCA_VZERO) {
-          t = -y / x;
-          c = 1 / Math.sqrt(t * t + 1);
-          s = t * c;
-        } else {
-          c = 1.0;
-          s = 0.0;
-        }
-      } else {
-        t = -x / y;
-        s = 1.0 / Math.sqrt(t * t + 1);
-        c = t * s;
-      }
-      w = dv_x - dv_y;// w = dv->v[k] -dv->v[k+1];
-      t = (w * s + 2 * c * ev1) * s;// t = (w * s +2 * c *ev->v[k+1]) *s;
-      dv_x -= t;// dv->v[k] -= t;
-      dv_y += t;// dv->v[k+1] += t;
-      ev1 += s * (c * w - 2 * s * ev1);// ev->v[k+1]+= s * (c* w- 2* s *ev->v[k+1]);
-      x = mat00;// x = a->m[k*dim+i];
-      y = mat10;// y = a->m[(k+1)*dim+i];
-      mat00 = c * x - s * y;// a->m[k*dim+i] = c * x - s* y;
-      mat10 = s * x + c * y;// a->m[(k+1)*dim+i] = s* x + c * y;
-      x = mat01;// x = a->m[k*dim+i];
-      y = mat11;// y = a->m[(k+1)*dim+i];
-      mat01 = c * x - s * y;// a->m[k*dim+i] = c * x - s* y;
-      mat11 = s * x + c * y;// a->m[(k+1)*dim+i] = s* x + c * y;
-    } while (Math.abs(ev1) > this.PCA_EPS * (Math.abs(dv_x) + Math.abs(dv_y)));
-    // }
-    t = dv_x;// t = dv->v[h];
-    if (dv_y > t) {// if( dv->v[i] > t ) {
-      t = dv_y;// t = dv->v[h];
-      dv_y = dv_x;// dv->v[h] = dv->v[k];
-      dv_x = t;// dv->v[k] = t;
-      // 行の入れ替え
-      o_matrix.m00 = mat10;
-      o_matrix.m01 = mat11;
-      o_matrix.m10 = mat00;
-      o_matrix.m11 = mat01;
-    } else {
-      // 行の入れ替えはなし
-      o_matrix.m00 = mat00;
-      o_matrix.m01 = mat01;
-      o_matrix.m10 = mat10;
-      o_matrix.m11 = mat11;
-    }
-    dv[0]=dv_x;
-    dv[1]=dv_y;
-    return;
-  }
-  /**
-   * static int PCA( ARMat *input, ARMat *output, ARVec *ev )
-   *
-   * @param output
-   * @param o_ev
-   * @throws NyARException
-   */
-  ,PCA_PCA : function(i_v1,i_v2,i_number_of_data,o_matrix,o_ev,o_mean)
-  {
-    var i;
-    // double[] mean_array=mean.getArray();
-    // mean.zeroClear();
-    //PCA_EXの処理
-    var sx = 0;
-    var sy = 0;
-    for (i = 0; i < i_number_of_data; i++) {
-      sx += i_v1[i];
-      sy += i_v2[i];
-    }
-    sx = sx / i_number_of_data;
-    sy = sy / i_number_of_data;
-    //PCA_CENTERとPCA_xt_by_xを一緒に処理
-    var srow = Math.sqrt((i_number_of_data));
-    var w00, w11, w10;
-    w00 = w11 = w10 = 0.0;// *out = 0.0;
-    for (i = 0; i < i_number_of_data; i++) {
-      var x = (i_v1[i] - sx) / srow;
-      var y = (i_v2[i] - sy) / srow;
-      w00 += (x * x);// *out += *in1 * *in2;
-      w10 += (x * y);// *out += *in1 * *in2;
-      w11 += (y * y);// *out += *in1 * *in2;
-    }
-    o_matrix.m00=w00;
-    o_matrix.m01=o_matrix.m10=w10;
-    o_matrix.m11=w11;
-    //PCA_PCAの処理
-    this.PCA_QRM(o_matrix, o_ev);
-    // m2 = o_output.m;// m2 = output->m;
-    if (o_ev[0] < this.PCA_VZERO) {// if( ev->v[i] < VZERO ){
-      o_ev[0] = 0.0;// ev->v[i] = 0.0;
-      o_matrix.m00 = 0.0;// *(m2++) = 0.0;
-      o_matrix.m01 = 0.0;// *(m2++) = 0.0;
-    }
-    if (o_ev[1] < this.PCA_VZERO) {// if( ev->v[i] < VZERO ){
-      o_ev[1] = 0.0;// ev->v[i] = 0.0;
-      o_matrix.m10 = 0.0;// *(m2++) = 0.0;
-      o_matrix.m11 = 0.0;// *(m2++) = 0.0;
-    }
-    o_mean[0]=sx;
-    o_mean[1]=sy;
-    // }
-    return;
-  }
-  ,pca : function(i_v1,i_v2,i_number_of_point,o_evec,o_ev,o_mean)
-  {
-    this.PCA_PCA(i_v1,i_v2,i_number_of_point,o_evec, o_ev,o_mean);
-    var sum = o_ev[0] + o_ev[1];
-    // For順変更禁止
-    o_ev[0] /= sum;// ev->v[i] /= sum;
-    o_ev[1] /= sum;// ev->v[i] /= sum;
-    return;
-  }
-})
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * JSARToolkit
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- *   Hirokazu Kato
- *   Mark Billinghurst
- *   HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * And the NyARToolkitAS3 ARToolKit class library.
- *   Copyright (C)2010 Ryo Iizuka
- *
- * JSARToolkit is a JavaScript port of NyARToolkitAS3.
- *   Copyright (C)2010 Ilmari Heikkinen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  ilmari.heikkinen@gmail.com
- *
- */
-
-/**
- * R8G8B8でピクセルを読み出すインタフェイス
- *
- */
-INyARRgbPixelReader = ASKlass('INyARRgbPixelReader', {
-  /**
-   * 1ピクセルをint配列にして返します。
-   *
-   * @param i_x
-   * @param i_y
-   * @param o_rgb
-   */
-  getPixel : function(i_x, i_y, o_rgb){},
-  /**
-   * 複数のピクセル値をi_rgbへ返します。
-   *
-   * @param i_x
-   * xのインデックス配列
-   * @param i_y
-   * yのインデックス配列
-   * @param i_num
-   * 返すピクセル値の数
-   * @param i_rgb
-   * ピクセル値を返すバッファ
-   */
-  getPixelSet : function(i_x, i_y, i_num, o_rgb){},
-  /**
-   * 1ピクセルを設定します。
-   * @param i_x
-   * @param i_y
-   * @param i_rgb
-   * @throws NyARException
-   */
-  setPixel : function(i_x, i_y, i_rgb){},
-  /**
-   * 複数のピクセル値をint配列から設定します。
-   * @param i_x
-   * @param i_y
-   * @param i_num
-   * @param i_intrgb
-   * @throws NyARException
-   */
-  setPixels : function(i_x, i_y, i_num, i_intrgb){},
-  switchBuffer : function(i_ref_buffer){}
-})
-NyARRgbPixelReader_INT1D_X8R8G8B8_32 = ASKlass('NyARRgbPixelReader_INT1D_X8R8G8B8_32', INyARRgbPixelReader,
-{
-  _ref_buf : null,
-  _size : null,
-  NyARRgbPixelReader_INT1D_X8R8G8B8_32 : function(i_buf, i_size)
-  {
-    this._ref_buf = i_buf;
-    this._size = i_size;
-  }
-  ,getPixel : function(i_x,i_y,o_rgb)
-  {
-    var rgb= this._ref_buf[i_x + i_y * this._size.w];
-    o_rgb[0] = (rgb>>16)&0xff;// R
-    o_rgb[1] = (rgb>>8)&0xff;// G
-    o_rgb[2] = rgb&0xff;// B
-    return;
-  }
-  ,getPixelSet : function(i_x,i_y,i_num, o_rgb)
-  {
-    var width = this._size.w;
-    var ref_buf = this._ref_buf;
-    for (var i = i_num - 1; i >= 0; i--) {
-      var rgb=ref_buf[i_x[i] + i_y[i] * width];
-      o_rgb[i * 3 + 0] = (rgb>>16)&0xff;// R
-      o_rgb[i * 3 + 1] = (rgb>>8)&0xff;// G
-      o_rgb[i * 3 + 2] = rgb&0xff;// B
-    }
-    return;
-  }
-  ,setPixel : function(i_x,i_y,i_rgb)
-  {
-    this._ref_buf[i_x + i_y * this._size.w]=((i_rgb[0]<<16)&0xff)|((i_rgb[1]<<8)&0xff)|((i_rgb[2])&0xff);
-  }
-  ,setPixels : function(i_x,i_y, i_num,i_intrgb)
-  {
-    throw new NyARException();
-  }
-  /**
-   * 参照しているバッファをi_ref_bufferへ切り替えます。
-   * 内部パラメータのチェックは、実装依存です。
-   * @param i_ref_buffer
-   * @throws NyARException
-   */
-  ,switchBuffer : function(i_ref_buffer)
-  {
-    NyAS3Utils.assert(i_ref_buffer.length>=this._size.w*this._size.h);
-    this._ref_buf = (i_ref_buffer);
-  }
-})
-
-
-NyARRgbPixelReader_Canvas2D = ASKlass("NyARRgbPixelReader_Canvas2D", INyARRgbPixelReader,
-{
-  _ref_canvas: null,
-  _data : null,
-
-  NyARRgbPixelReader_Canvas2D : function(i_canvas)
-  {
-    this._ref_canvas = i_canvas;
-  },
-
-  getData : function() {
-    if (this._ref_canvas.changed || !this._data) {
-      var canvas = this._ref_canvas;
-      var ctx = canvas.getContext('2d');
-      this._data = ctx.getImageData(0,0,canvas.width,canvas.height);
-      this._ref_canvas.changed = false;
-    }
-    return this._data;
-  },
-
-  getPixel: function(i_x, i_y, o_rgb)
-  {
-    var idata = this.getData();
-    var w = idata.width;
-    var h = idata.height;
-    var d = idata.data;
-    o_rgb[0] = d[i_y*w+i_x];// R
-    o_rgb[1] = d[i_y*w+i_x+1];// G
-    o_rgb[2] = d[i_y*w+i_x+2];// B
-    return;
-  },
-
-  getPixelSet: function(i_x, i_y, i_num, o_rgb)
-  {
-    var idata = this.getData();
-    var w = idata.width;
-    var h = idata.height;
-    var d = idata.data;
-    for (var i = 0; i < i_num; i++) {
-      var idx = i_y[i]*w*4 + i_x[i]*4;
-      o_rgb[i*3+0] = d[idx+0];
-      o_rgb[i*3+1] = d[idx+1];
-      o_rgb[i*3+2] = d[idx+2];
-    }
-  },
-
-  setPixel: function(i_x, i_y, i_rgb)
-  {
-    NyARException.notImplement();
-  },
-  setPixels: function(i_x, i_y, i_num, i_intrgb)
-  {
-    NyARException.notImplement();
-  },
-  switchBuffer:function(i_canvas)
-  {
-    NyARException.notImplement();
-  }
-
-})
-
-// END FILE: 
-
-// BEGIN FILE: 
-/*
-* JSARToolkit
-* --------------------------------------------------------------------------------
-* This work is based on the original ARToolKit developed by
-*   Hirokazu Kato
-*   Mark Billinghurst
-*   HITLab, University of Washington, Seattle
-* http://www.hitl.washington.edu/artoolkit/
-*
-* And the NyARToolkitAS3 ARToolKit class library.
-*   Copyright (C)2010 Ryo Iizuka
-*
-* JSARToolkit is a JavaScript port of NyARToolkitAS3.
-*   Copyright (C)2010 Ilmari Heikkinen
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*
-* For further information please contact.
-*   ilmari.heikkinen@gmail.com
-*
-*/
-
-
-
-
-INyARDoubleMatrix = Klass({
-
-  /**
-    * 配列の内容を行列に設定する。
-    * 遅いので余り使わないでね。
-    * @param o_value
-    */
-  setValue : function(o_value){}, // double[]
-
-  /**
-    * 行列の内容を配列に返す。
-    * 遅いので余り使わないでね。
-    * @param o_value
-    */
-  getValue : function(o_value){} // double[]
-})
-
-
-
-NyARDoubleMatrix22 = Klass(INyARDoubleMatrix,
-{
-  m00 : 0,
-  m01 : 0,
-  m10 : 0,
-  m11 : 0,
-  /**
-    * 遅いからあんまり使わないでね。
-    */
-  setValue : function(i_value)
-  {
-    this.m00=i_value[0];
-    this.m01=i_value[1];
-    this.m10=i_value[3];
-    this.m11=i_value[4];
-    return;
-  }
-  /**
-    * 遅いからあんまり使わないでね。
-    */
-  ,getValue : function(o_value)
-  {
-    o_value[0]=this.m00;
-    o_value[1]=this.m01;
-    o_value[3]=this.m10;
-    o_value[4]=this.m11;
-    return;
-  }
-  ,inverse : function(i_src)
-  {
-    var a11,a12,a21,a22;
-    a11=i_src.m00;
-    a12=i_src.m01;
-    a21=i_src.m10;
-    a22=i_src.m11;
-    var det=a11*a22-a12*a21;
-    if(det==0){
-      return false;
-    }
-    det=1/det;
-    this.m00=a22*det;
-    this.m01=-a12*det;
-    this.m10=-a21*det;
-    this.m11=a11*det;
-    return true;
-  }
-})
-
-
-
-
-
-
-
-NyARDoubleMatrix33 = Klass( INyARDoubleMatrix,
-{
-  m00 : 0,
-  m01 : 0,
-  m02 : 0,
-  m10 : 0,
-  m11 : 0,
-  m12 : 0,
-  m20 : 0,
-  m21 : 0,
-  m22 : 0,
-  createArray : function(i_number)
-  {
-    var ret=new Array(i_number);
-    for(var i=0;i<i_number;i++)
-    {
-      ret[i]=new NyARDoubleMatrix33();
-    }
-    return ret;
-  }
-  /**
-    * 遅いからあんまり使わないでね。
-    */
-  ,setValue : function(i_value)
-  {
-    this.m00=i_value[0];
-    this.m01=i_value[1];
-    this.m02=i_value[2];
-    this.m10=i_value[3];
-    this.m11=i_value[4];
-    this.m12=i_value[5];
-    this.m20=i_value[6];
-    this.m21=i_value[7];
-    this.m22=i_value[8];
-    return;
-  }
-  ,setValue_NyARDoubleMatrix33 : function(i_value)
-  {
-    this.m00=i_value.m00;
-    this.m01=i_value.m01;
-    this.m02=i_value.m02;
-    this.m10=i_value.m10;
-    this.m11=i_value.m11;
-    this.m12=i_value.m12;
-    this.m20=i_value.m20;
-    this.m21=i_value.m21;
-    this.m22=i_value.m22;
-    return;
-  }
-  /**
-    * 遅いからあんまり使わないでね。
-    */
-  ,getValue : function(o_value)
-  {
-    o_value[0]=this.m00;
-    o_value[1]=this.m01;
-    o_value[2]=this.m02;
-    o_value[3]=this.m10;
-    o_value[4]=this.m11;
-    o_value[5]=this.m12;
-    o_value[6]=this.m20;
-    o_value[7]=this.m21;
-    o_value[8]=this.m22;
-    return;
-  }
-  ,inverse : function(i_src)
-  {
-    var a11,a12,a13,a21,a22,a23,a31,a32,a33;
-    var b11,b12,b13,b21,b22,b23,b31,b32,b33;
-    a11=i_src.m00;a12=i_src.m01;a13=i_src.m02;
-    a21=i_src.m10;a22=i_src.m11;a23=i_src.m12;
-    a31=i_src.m20;a32=i_src.m21;a33=i_src.m22;
-
-    b11=a22*a33-a23*a32;
-    b12=a32*a13-a33*a12;
-    b13=a12*a23-a13*a22;
-
-    b21=a23*a31-a21*a33;
-    b22=a33*a11-a31*a13;
-    b23=a13*a21-a11*a23;
-
-    b31=a21*a32-a22*a31;
-    b32=a31*a12-a32*a11;
-    b33=a11*a22-a12*a21;
-
-    var det_1=a11*b11+a21*b12+a31*b13;
-    if(det_1==0){
-      return false;
-    }
-    det_1=1/det_1;
-
-    this.m00=b11*det_1;
-    this.m01=b12*det_1;
-    this.m02=b13*det_1;
-
-    this.m10=b21*det_1;
-    this.m11=b22*det_1;
-    this.m12=b23*det_1;
-
-    this.m20=b31*det_1;
-    this.m21=b32*det_1;
-    this.m22=b33*det_1;
-
-    return true;
-  }
-  /**
-    * この関数は、0-PIの間で値を返します。
-    * @param o_out
-    */
-  ,getZXYAngle : function(o_out)
-  {
-    var sina = this.m21;
-    if (sina >= 1.0) {
-      o_out.x = Math.PI / 2;
-      o_out.y = 0;
-      o_out.z = Math.atan2(-this.m10, this.m00);
-    } else if (sina <= -1.0) {
-      o_out.x = -Math.PI / 2;
-      o_out.y = 0;
-      o_out.z = Math.atan2(-this.m10, this.m00);
-    } else {
-      o_out.x = Math.asin(sina);
-      o_out.z = Math.atan2(-this.m01, this.m11);
-      o_out.y = Math.atan2(-this.m20, this.m22);
-    }
-  }
-  ,setZXYAngle_NyARDoublePoint3d : function(i_angle)
-  {
-    this.setZXYAngle_Number(i_angle.x,i_angle.y,i_angle.z);
-    return;
-  }
-  ,setZXYAngle_Number : function(i_x,i_y,i_z)
-  {
-    var sina = Math.sin(i_x);
-    var cosa = Math.cos(i_x);
-    var sinb = Math.sin(i_y);
-    var cosb = Math.cos(i_y);
-    var sinc = Math.sin(i_z);
-    var cosc = Math.cos(i_z);
-    this.m00 = cosc * cosb - sinc * sina * sinb;
-    this.m01 = -sinc * cosa;
-    this.m02 = cosc * sinb + sinc * sina * cosb;
-    this.m10 = sinc * cosb + cosc * sina * sinb;
-    this.m11 = cosc * cosa;
-    this.m12 = sinc * sinb - cosc * sina * cosb;
-    this.m20 = -cosa * sinb;
-    this.m21 = sina;
-    this.m22 = cosb * cosa;
-    return;
-  }
-  /**
-    * 回転行列を適応して座標変換します。
-    * @param i_angle
-    * @param o_out
-    */
-  ,transformVertex_NyARDoublePoint3d : function(i_position,o_out)
-  {
-    transformVertex_double(i_position.x,i_position.y,i_position.z,o_out);
-    return;
-  }
-
-  ,transformVertex_double : function(i_x,i_y,i_z,o_out)
-  {
-    o_out.x=this.m00*i_x+this.m01*i_y+this.m02*i_z;
-    o_out.y=this.m10*i_x+this.m11*i_y+this.m12*i_z;
-    o_out.z=this.m20*i_x+this.m21*i_y+this.m22*i_z;
-    return;
-  }
-})
-
-
-
-
-
-NyARDoubleMatrix34 = Klass( INyARDoubleMatrix,
-{
-
-  m00 : 0,
-  m01 : 0,
-  m02 : 0,
-  m03 : 0,
-  m10 : 0,
-  m11 : 0,
-  m12 : 0,
-  m13 : 0,
-  m20 : 0,
-  m21 : 0,
-  m22 : 0,
-  m23 : 0,
-
-  setValue : function(i_value)
-  {
-    this.m00 = i_value[0];
-    this.m01 = i_value[1];
-    this.m02 = i_value[2];
-    this.m03 = i_value[3];
-    this.m10 = i_value[4];
-    this.m11 = i_value[5];
-    this.m12 = i_value[6];
-    this.m13 = i_value[7];
-    this.m20 = i_value[8];
-    this.m21 = i_value[9];
-    this.m22 = i_value[10];
-    this.m23 = i_value[11];
-    return;
-  }
-  ,setValue_NyARDoubleMatrix34 : function(i_value)
-  {
-    this.m00=i_value.m00;
-    this.m01=i_value.m01;
-    this.m02=i_value.m02;
-    this.m03=i_value.m03;
-    this.m10=i_value.m10;
-    this.m11=i_value.m11;
-    this.m12=i_value.m12;
-    this.m13=i_value.m13;
-    this.m20=i_value.m20;
-    this.m21=i_value.m21;
-    this.m22=i_value.m22;
-    this.m23=i_value.m23;
-    return;
-  }
-
-  ,getValue : function(o_value)
-  {
-    o_value[0] = this.m00;
-    o_value[1] = this.m01;
-    o_value[2] = this.m02;
-    o_value[3] = this.m03;
-    o_value[4] = this.m10;
-    o_value[5] = this.m11;
-    o_value[6] = this.m12;
-    o_value[7] = this.m13;
-    o_value[8] = this.m20;
-    o_value[9] = this.m21;
-    o_value[10] = this.m22;
-    o_value[11] = this.m23;
-    return;
-  }
-})
-
-
-
-NyARDoubleMatrix44 = Klass( INyARDoubleMatrix,
-{
-  m00 : 0,
-  m01 : 0,
-  m02 : 0,
-  m03 : 0,
-  m10 : 0,
-  m11 : 0,
-  m12 : 0,
-  m13 : 0,
-  m20 : 0,
-  m21 : 0,
-  m22 : 0,
-  m23 : 0,
-  m30 : 0,
-  m31 : 0,
-  m32 : 0,
-  m33 : 0,
-  createArray : function(i_number)
-  {
-    var ret=new Array(i_number);
-    for(var i=0;i<i_number;i++)
-    {
-      ret[i]=new NyARDoubleMatrix44();
-    }
-    return ret;
-  }
-  /**
-    * 遅いからあんまり使わないでね。
-    */
-  ,setValue : function(i_value)
-  {
-    this.m00=i_value[ 0];
-    this.m01=i_value[ 1];
-    this.m02=i_value[ 2];
-    this.m03=i_value[ 3];
-    this.m10=i_value[ 4];
-    this.m11=i_value[ 5];
-    this.m12=i_value[ 6];
-    this.m13=i_value[ 7];
-    this.m20=i_value[ 8];
-    this.m21=i_value[ 9];
-    this.m22=i_value[10];
-    this.m23=i_value[11];
-    this.m30=i_value[12];
-    this.m31=i_value[13];
-    this.m32=i_value[14];
-    this.m33=i_value[15];
-    return;
-  }
-  /**
-    * 遅いからあんまり使わないでね。
-    */
-  ,getValue : function(o_value)
-  {
-    o_value[ 0]=this.m00;
-    o_value[ 1]=this.m01;
-    o_value[ 2]=this.m02;
-    o_value[ 3]=this.m03;
-    o_value[ 4]=this.m10;
-    o_value[ 5]=this.m11;
-    o_value[ 6]=this.m12;
-    o_value[ 7]=this.m13;
-    o_value[ 8]=this.m20;
-    o_value[ 9]=this.m21;
-    o_value[10]=this.m22;
-    o_value[11]=this.m23;
-    o_value[12]=this.m30;
-    o_value[13]=this.m31;
-    o_value[14]=this.m32;
-    o_value[15]=this.m33;
-    return;
-  }
-  ,inverse : function(i_src)
-  {
-    var a11,a12,a13,a14,a21,a22,a23,a24,a31,a32,a33,a34,a41,a42,a43,a44;
-    var b11,b12,b13,b14,b21,b22,b23,b24,b31,b32,b33,b34,b41,b42,b43,b44;
-    var t1,t2,t3,t4,t5,t6;
-    a11=i_src.m00;a12=i_src.m01;a13=i_src.m02;a14=i_src.m03;
-    a21=i_src.m10;a22=i_src.m11;a23=i_src.m12;a24=i_src.m13;
-    a31=i_src.m20;a32=i_src.m21;a33=i_src.m22;a34=i_src.m23;
-    a41=i_src.m30;a42=i_src.m31;a43=i_src.m32;a44=i_src.m33;
-
-    t1=a33*a44-a34*a43;
-    t2=a34*a42-a32*a44;
-    t3=a32*a43-a33*a42;
-    t4=a34*a41-a31*a44;
-    t5=a31*a43-a33*a41;
-    t6=a31*a42-a32*a41;
-
-    b11=a22*t1+a23*t2+a24*t3;
-    b21=-(a23*t4+a24*t5+a21*t1);
-    b31=a24*t6-a21*t2+a22*t4;
-    b41=-(a21*t3-a22*t5+a23*t6);
-
-    t1=a43*a14-a44*a13;
-    t2=a44*a12-a42*a14;
-    t3=a42*a13-a43*a12;
-    t4=a44*a11-a41*a14;
-    t5=a41*a13-a43*a11;
-    t6=a41*a12-a42*a11;
-
-    b12=-(a32*t1+a33*t2+a34*t3);
-    b22=a33*t4+a34*t5+a31*t1;
-    b32=-(a34*t6-a31*t2+a32*t4);
-    b42=a31*t3-a32*t5+a33*t6;
-
-    t1=a13*a24-a14*a23;
-    t2=a14*a22-a12*a24;
-    t3=a12*a23-a13*a22;
-    t4=a14*a21-a11*a24;
-    t5=a11*a23-a13*a21;
-    t6=a11*a22-a12*a21;
-
-    b13=a42*t1+a43*t2+a44*t3;
-    b23=-(a43*t4+a44*t5+a41*t1);
-    b33=a44*t6-a41*t2+a42*t4;
-    b43=-(a41*t3-a42*t5+a43*t6);
-
-    t1=a23*a34-a24*a33;
-    t2=a24*a32-a22*a34;
-    t3=a22*a33-a23*a32;
-    t4=a24*a31-a21*a34;
-    t5=a21*a33-a23*a31;
-    t6=a21*a32-a22*a31;
-
-    b14=-(a12*t1+a13*t2+a14*t3);
-    b24=a13*t4+a14*t5+a11*t1;
-    b34=-(a14*t6-a11*t2+a12*t4);
-    b44=a11*t3-a12*t5+a13*t6;
-
-    var det_1=(a11*b11+a21*b12+a31*b13+a41*b14);
-    if(det_1==0){
-      return false;
-    }
-    det_1=1/det_1;
-
-    this.m00=b11*det_1;
-    this.m01=b12*det_1;
-    this.m02=b13*det_1;
-    this.m03=b14*det_1;
-
-    this.m10=b21*det_1;
-    this.m11=b22*det_1;
-    this.m12=b23*det_1;
-    this.m13=b24*det_1;
-
-    this.m20=b31*det_1;
-    this.m21=b32*det_1;
-    this.m22=b33*det_1;
-    this.m23=b34*det_1;
-
-    this.m30=b41*det_1;
-    this.m31=b42*det_1;
-    this.m32=b43*det_1;
-    this.m33=b44*det_1;
-
-    return true;
-  }
-})
-
-
-
-
-
-/**
-  * スタック型の可変長配列。
-  * 配列には実体を格納します。
-  *
-  * 注意事項
-  * JavaのGenericsの制限突破を狙ったものの、Vector.&lt;*&gt;では、不具合が多いため、Vector.&lt;Object&gt;に変更
-  * いくつかの場所でエラーがでる場合がありますが、コンパイルオプションなどで、
-  * strict = false を設定して回避してください。
-  * 根本修正は次バージョン以降で対応する予定です。
-  */
-NyARObjectStack = Klass(
-{
-  _items : null,
-
-  _length : 0,
-
-  /**
-    * 最大ARRAY_MAX個の動的割り当てバッファを準備する。
-    *
-    *
-    * @param i_array
-    * @param i_element_type
-    */
-  initialize : function(i_length)
-  {
-    //領域確保
-    i_length = toInt(i_length);
-    this._items = this.createArray(i_length);
-    //使用中個数をリセット
-    this._length = 0;
-    return;
-  }
-
-  /**
-    * どのような配列(Vector)を格納するかを決める場所。
-    * この関数を上書きしてください。
-    *
-    */
-  ,createArray : function(i_length)
-  {
-    throw new NyARException();
-  }
-
-  /**
-    * 新しい領域を予約します。
-    * @return
-    * 失敗するとnull
-    * @throws NyARException
-    */
-  ,prePush : function()
-  {
-    // 必要に応じてアロケート
-    if (this._length >= this._items.length){
-      return null;
-    }
-    // 使用領域を+1して、予約した領域を返す。
-    var ret = this._items[this._length];
-    this._length++;
-    return ret;
-  }
-
-  /**
-    * スタックを初期化します。
-    * @param i_reserv_length
-    * 使用済みにするサイズ
-    * @return
-    */
-  ,init : function(i_reserv_length)
-  {
-    // 必要に応じてアロケート
-    if (i_reserv_length >= this._items.length){
-      throw new NyARException();
-    }
-    this._length=i_reserv_length;
-  }
-
-  /**
-    * 見かけ上の要素数を1減らして、そのオブジェクトを返します。
-    * 返却したオブジェクトの内容は、次回のpushまで有効です。
-    * @return
-    */
-  ,pop : function()
-  {
-    NyAS3Utils.assert(this._length>=1);
-    this._length--;
-    return this._items[this._length];
-  }
-
-  /**
-    * 見かけ上の要素数をi_count個減らします。
-    * @param i_count
-    * @return
-    */
-  ,pops : function(i_count)
-  {
-    NyAS3Utils.assert(this._length>=i_count);
-    this._length-=i_count;
-    return;
-  }
-
-  /**
-    * 配列を返します。
-    *
-    * @return
-    */
-  ,getArray : function()
-  {
-    return this._items;
-  }
-
-  ,getItem : function(i_index)
-  {
-    return this._items[i_index];
-  }
-
-  /**
-    * 配列の見かけ上の要素数を返却します。
-    * @return
-    */
-  ,getLength : function()
-  {
-    return this._length;
-  }
-
-  /**
-    * 見かけ上の要素数をリセットします。
-    */
-  ,clear : function()
-  {
-    this._length = 0;
-  }
-})
-
-/**
-  * ...
-  * @author
-  */
-NyARIntPointStack = Klass( NyARObjectStack,
-{
-  initialize : function(i_length)
-  {
-    NyARObjectStack.initialize.call(this, i_length);
-  }
-  ,createArray : function(i_length)
-  {
-    var ret= new Array(i_length);
-    for (var i =0; i < i_length; i++){
-      ret[i] = new NyARIntPoint2d();
-    }
-    return ret;
-  }
-
-})
-
-
-
-
-
-
-
-//	import jp.nyatla.nyartoolkit.as3.core.types.*;
-
-NyARIntRectStack = Klass( //NyARObjectStack,
-{
-  _items : null,
-
-  _length : null,
-
-  initialize : function(i_length)
-  {
-    //領域確保
-    this._items = this.createArray(i_length);
-    //使用中個数をリセット
-    this._length = 0;
-    return;
-  }
-  ,createArray : function(i_length)
-  {
-    var ret= new Array(i_length);
-    for (var i =0; i < i_length; i++){
-      ret[i] = new  NyARIntRect();
-    }
-    return ret;
-  }
-  /**
-    * 新しい領域を予約します。
-    * @return
-    * 失敗するとnull
-    * @throws NyARException
-    */
-  ,prePush : function()
-  {
-    // 必要に応じてアロケート
-    if (this._length >= this._items.length){
-      return null;
-    }
-    // 使用領域を+1して、予約した領域を返す。
-    var ret = this._items[this._length];
-    this._length++;
-    return ret;
-  }
-
-  /**
-    * スタックを初期化します。
-    * @param i_reserv_length
-    * 使用済みにするサイズ
-    * @return
-    */
-  ,init : function(i_reserv_length)
-  {
-    // 必要に応じてアロケート
-    if (i_reserv_length >= this._items.length){
-      throw new NyARException();
-    }
-    this._length=i_reserv_length;
-  }
-
-  /**
-    * 見かけ上の要素数を1減らして、そのオブジェクトを返します。
-    * 返却したオブジェクトの内容は、次回のpushまで有効です。
-    * @return
-    */
-  ,pop : function()
-  {
-    NyAS3Utils.assert(this._length>=1);
-    this._length--;
-    return this._items[this._length];
-  }
-
-  /**
-    * 見かけ上の要素数をi_count個減らします。
-    * @param i_count
-    * @return
-    */
-  ,pops : function(i_count)
-  {
-    NyAS3Utils.assert(this._length>=i_count);
-    this._length-=i_count;
-    return;
-  }
-
-  /**
-    * 配列を返します。
-    *
-    * @return
-    */
-  ,getArray : function()
-  {
-    return this._items;
-  }
-
-  ,getItem : function(i_index)
-  {
-    return this._items[i_index];
-  }
-
-  /**
-    * 配列の見かけ上の要素数を返却します。
-    * @return
-    */
-  ,getLength : function()
-  {
-    return this._length;
-  }
-
-  /**
-    * 見かけ上の要素数をリセットします。
-    */
-  ,clear : function()
-  {
-    this._length = 0;
-  }
-})
-
-
-
-
-
-
-
-
-
-NyARBufferType = Klass(
-  (function() {
-    var T_BYTE1D =0x00010000;
-    var T_INT2D  =0x00020000;
-    var T_SHORT1D=0x00030000;
-    var T_INT1D  =0x00040000;
-    var T_OBJECT =0x00100000;
-    var T_USER   =0x00FF0000;
-
-    return ({
-      //  24-31(8)予約
-      //  16-27(8)型ID
-      //      00:無効/01[]/02[][]/03[]
-      //  08-15(8)ビットフォーマットID
-      //      00/01/02
-      //  00-07(8)型番号
-      //
-      /**
-        * RGB24フォーマットで、全ての画素が0
-        */
-      NULL_ALLZERO : 0x00000001,
-      /**
-        * USER - USER+0xFFFFはユーザー定義型。実験用に。
-        */
-      USER_DEFINE  : T_USER,
-
-      /**
-        * byte[]で、R8G8B8の24ビットで画素が格納されている。
-        */
-      BYTE1D_R8G8B8_24   : T_BYTE1D|0x0001,
-      /**
-        * byte[]で、B8G8R8の24ビットで画素が格納されている。
-        */
-      BYTE1D_B8G8R8_24   : T_BYTE1D|0x0002,
-      /**
-        * byte[]で、R8G8B8X8の32ビットで画素が格納されている。
-        */
-      BYTE1D_B8G8R8X8_32 : T_BYTE1D|0x0101,
-      /**
-        * byte[]で、X8R8G8B8の32ビットで画素が格納されている。
-        */
-      BYTE1D_X8R8G8B8_32 : T_BYTE1D|0x0102,
-
-      /**
-        * byte[]で、RGB565の16ビット(little/big endian)で画素が格納されている。
-        */
-      BYTE1D_R5G6B5_16LE : T_BYTE1D|0x0201,
-      BYTE1D_R5G6B5_16BE : T_BYTE1D|0x0202,
-      /**
-        * short[]で、RGB565の16ビット(little/big endian)で画素が格納されている。
-        */
-      WORD1D_R5G6B5_16LE : T_SHORT1D|0x0201,
-      WORD1D_R5G6B5_16BE : T_SHORT1D|0x0202,
-
-
-      /**
-        * int[][]で特に値範囲を定めない
-        */
-      INT2D        : T_INT2D|0x0000,
-      /**
-        * int[][]で0-255のグレイスケール画像
-        */
-      INT2D_GRAY_8 : T_INT2D|0x0001,
-      /**
-        * int[][]で0/1の2値画像
-        * これは、階調値1bitのBUFFERFORMAT_INT2D_GRAY_1と同じです。
-        */
-      INT2D_BIN_8  : T_INT2D|0x0002,
-
-      /**
-        * int[]で特に値範囲を定めない
-        */
-      INT1D        : T_INT1D|0x0000,
-      /**
-        * int[]で0-255のグレイスケール画像
-        */
-      INT1D_GRAY_8 : T_INT1D|0x0001,
-      /**
-        * int[]で0/1の2値画像
-        * これは、階調1bitのINT1D_GRAY_1と同じです。
-        */
-      INT1D_BIN_8  : T_INT1D|0x0002,
-
-
-      /**
-        * int[]で、XRGB32の32ビットで画素が格納されている。
-        */
-      INT1D_X8R8G8B8_32:T_INT1D|0x0102,
-
-      /**
-        * H(0-359),S(0-255),V(0-255)
-        */
-      INT1D_X7H9S8V8_32:T_INT1D|0x0103,
-
-
-      /**
-        * プラットフォーム固有オブジェクト
-        */
-      OBJECT_Java: T_OBJECT|0x0100,
-      OBJECT_CS  : T_OBJECT|0x0200,
-      OBJECT_AS3 : T_OBJECT|0x0300,
-      OBJECT_JS : T_OBJECT|0x0400,
-
-      /**
-        * JavaのBufferedImageを格納するラスタ
-        */
-      OBJECT_Java_BufferedImage: T_OBJECT|0x0100|0x01,
-
-      OBJECT_AS3_BitmapData : T_OBJECT|0x0300|0x01,
-      /**
-        * JavaScriptのCanvasを格納するラスタ
-        */
-      OBJECT_JS_Canvas : T_OBJECT|0x0400|0x01
-    });
-  })()
-)
-
-
-
-
-
-NyARDoublePoint2d = Klass(
-{
-  x : 0,
-  y : 0,
-  /**
-    * 配列ファクトリ
-    * @param i_number
-    * @return
-    */
-  createArray : function(i_number)
-  {
-    var ret=new Array(i_number);
-    for(var i=0;i<i_number;i++)
-    {
-      ret[i]=new NyARDoublePoint2d();
-    }
-    return ret;
-  }
-  ,initialize : function()
-  {
-    switch(arguments.length) {
-    case 0:
-      {//public function NyARDoublePoint2d()
-        this.x = 0;
-        this.y = 0;
-      }
-      return;
-    case 1:
-      this.x=args[0].x;
-      this.y=args[0].y;
-      return;
-      break;
-    case 2:
-      {	//public function NyARDoublePoint2d(i_x,i_y)
-        this.x = Number(args[0]);
-        this.y = Number(args[1]);
-        return;
-      }
-    default:
-      break;
-    }
-    throw new NyARException();
-  }
-  ,setValue_NyARDoublePoint2d : function(i_src)
-  {
-    this.x=i_src.x;
-    this.y=i_src.y;
-    return;
-  }
-  ,setValue_NyARIntPoint2d : function(i_src)
-  {
-    this.x=(i_src.x);
-    this.y=(i_src.y);
-    return;
-  }
-  /**
-    * 格納値をベクトルとして、距離を返します。
-    * @return
-    */
-  ,dist : function()
-  {
-    return Math.sqrt(this.x*this.x+this.y+this.y);
-  }
-  ,sqNorm : function()
-  {
-    return this.x*this.x+this.y+this.y;
-  }
-})
-
-
-
-
-
-NyARDoublePoint3d = Klass(
-{
-  x : 0,
-  y : 0,
-  z : 0,
-  /**
-    * 配列ファクトリ
-    * @param i_number
-    * @return
-    */
-  createArray : function(i_number)
-  {
-    var ret=new Array(i_number);
-    for(var i=0;i<i_number;i++)
-    {
-      ret[i]=new NyARDoublePoint3d();
-    }
-    return ret;
-  }
-  ,setValue : function(i_in)
-  {
-    this.x=i_in.x;
-    this.y=i_in.y;
-    this.z=i_in.z;
-    return;
-  }
-  /**
-    * i_pointとのベクトルから距離を計算します。
-    * @return
-    */
-  ,dist : function(i_point)
-  {
-    var x,y,z;
-    x=this.x-i_point.x;
-    y=this.y-i_point.y;
-    z=this.z-i_point.z;
-    return Math.sqrt(x*x+y*y+z*z);
-  }
-})
-
-
-
-
-/**
-  * ヒストグラムを格納するクラスです。
-  */
-NyARHistogram = Klass(
-{
-  /**
-    * サンプリング値の格納変数
-    */
-  data : null,
-  /**
-    * 有効なサンプリング値の範囲。[0-data.length-1]
-    */
-  length : 0,
-  /**
-    * 有効なサンプルの総数 data[i]
-    */
-  total_of_data : 0,
-
-
-
-  initialize : function(i_length)
-  {
-    this.data=new FloatVector(i_length);
-    this.length=i_length;
-    this.total_of_data=0;
-  }
-  /**
-    * 区間i_stからi_edまでの総データ数を返します。
-    * @param i_st
-    * @param i_ed
-    * @return
-    */
-  ,getTotal : function(i_st,i_ed)
-  {
-    NyAS3Utils.assert(i_st<i_ed && i_ed<this.length);
-    var result=0;
-    var s=this.data;
-    for(var i=i_st;i<=i_ed;i++){
-      result+=s[i];
-    }
-    return result;
-  }
-  /**
-    * 指定したi_pos未満サンプルを０にします。
-    * @param i_pos
-    */
-  ,lowCut : function(i_pos)
-  {
-    var s= 0;
-    for(var i=0;i<i_pos;i++){
-      s+=this.data[i];
-      this.data[i]=0;
-    }
-    this.total_of_data-=s;
-  }
-  /**
-    * 指定したi_pos以上のサンプルを０にします。
-    * @param i_pos
-    */
-  ,highCut : function(i_pos)
-  {
-    var s=0;
-    for(var i=this.length-1;i>=i_pos;i--){
-      s+=this.data[i];
-      this.data[i]=0;
-    }
-    this.total_of_data-=s;
-  }
-  /**
-    * 最小の値が格納されているサンプル番号を返します。
-    */
-  ,getMinSample : function()
-  {
-    var data=this.data;
-    var ret=this.length-1;
-    var min=data[ret];
-    for(var i=this.length-2;i>=0;i--)
-    {
-      if(data[i]<min){
-        min=data[i];
-        ret=i;
-      }
-    }
-    return ret;
-  }
-  /**
-    * サンプルの中で最小の値を返します。
-    * @return
-    */
-  ,getMinData : function()
-  {
-    return this.data[this.getMinSample()];
-  }
-  /**
-    * 平均値を計算します。
-    * @return
-    */
-  ,getAverage : function()
-  {
-    var sum=0;
-    for(var i=this.length-1;i>=0;i--)
-    {
-      sum+=this.data[i]*i;
-    }
-    return toInt(sum/this.total_of_data);
-  }
-
-})
-
-
-
-
-
-NyARIntPoint2d = Klass(
-{
-  x : 0,
-
-  y : 0,
-  /**
-    * 配列ファクトリ
-    * @param i_number
-    * @return
-    */
-  createArray : function(i_number)
-  {
-    var ret=new Array(i_number);
-    for(var i=0;i<i_number;i++)
-    {
-      ret[i]=new NyARIntPoint2d();
-    }
-    return ret;
-  }
-  ,copyArray : function(i_from,i_to)
-  {
-    for(var i=i_from.length-1;i>=0;i--)
-    {
-      i_to[i].x=i_from[i].x;
-      i_to[i].y=i_from[i].y;
-    }
-    return;
-  }
-})
-
-
-
-
-
-NyARIntRect = Klass(
-{
-  x : 0,
-
-  y : 0,
-
-  w : 0,
-
-  h : 0
-})
-
-
-
-
-
-NyARIntSize = Klass(
-{
-  h : 0,
-  w : 0,
-  /*	public function NyARIntSize()
-    * 	public function NyARIntSize(i_width,i_height)
-    *	public function NyARIntSize(i_ref_object)
-  */
-  initialize : function()
-  {
-    switch(arguments.length) {
-    case 0:
-      {//public function NyARIntSize()
-        this.w = 0;
-        this.h = 0;
-        return;
-      }
-    case 1:
-      this.w = arguments[0].w;
-      this.h = arguments[0].h;
-      return;
-      break;
-    case 2:
-      {	//public function NyARIntSize(i_ref_object)
-        this.w=toInt(arguments[0]);
-        this.h=toInt(arguments[1]);
-        return;
-      }
-      break;
-    default:
-      break;
-    }
-    throw new NyARException();
-  }
-
-  /**
-    * サイズが同一であるかを確認する。
-    *
-    * @param i_width
-    * @param i_height
-    * @return
-    * @throws NyARException
-    */
-  ,isEqualSize_int : function(i_width,i_height)
-  {
-    if (i_width == this.w && i_height == this.h) {
-      return true;
-    }
-    return false;
-  }
-
-  /**
-    * サイズが同一であるかを確認する。
-    *
-    * @param i_width
-    * @param i_height
-    * @return
-    * @throws NyARException
-    */
-  ,isEqualSize_NyARIntSize : function(i_size)
-  {
-    if (i_size.w == this.w && i_size.h == this.h) {
-      return true;
-    }
-    return false;
-
-  }
-})
-
-
-
-
-/**
-  * 0=dx*x+dy*y+cのパラメータを格納します。
-  * x,yの増加方向は、x=L→R,y=B→Tです。
-  *
-  */
-NyARLinear = Klass(
-{
-  dx : 0,//dx軸の増加量
-  dy : 0,//dy軸の増加量
-  c : 0,//切片
-  createArray : function(i_number)
-  {
-    var ret=new Array(i_number);
-    for(var i=0;i<i_number;i++)
-    {
-      ret[i]=new NyARLinear();
-    }
-    return ret;
-  }
-  ,copyFrom : function(i_source)
-  {
-    this.dx=i_source.dx;
-    this.dy=i_source.dy;
-    this.c=i_source.c;
-    return;
-  }
-  /**
-    * 2直線の交点を計算します。
-    * @param l_line_i
-    * @param l_line_2
-    * @param o_point
-    * @return
-    */
-  ,crossPos : function(l_line_i,l_line_2 ,o_point)
-  {
-    var w1 = l_line_2.dy * l_line_i.dx - l_line_i.dy * l_line_2.dx;
-    if (w1 == 0.0) {
-      return false;
-    }
-    o_point.x = (l_line_2.dx * l_line_i.c - l_line_i.dx * l_line_2.c) / w1;
-    o_point.y = (l_line_i.dy * l_line_2.c - l_line_2.dy * l_line_i.c) / w1;
-    return true;
-  }
-})
-
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * PROJECT: FLARToolKit
- * --------------------------------------------------------------------------------
- * This work is based on the NyARToolKit developed by
- *   R.Iizuka (nyatla)
- * http://nyatla.jp/nyatoolkit/
- *
- * The FLARToolKit is ActionScript 3.0 version ARToolkit class library.
- * Copyright (C)2008 Saqoosha
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  http://www.libspark.org/wiki/saqoosha/FLARToolKit
- *  <saq(at)saqoosha.net>
- *
- */
-
-
-
-/**
- * 各ラスタ用のフィルタ実装
- */
-IFLdoThFilterImpl = ASKlass('IFLdoThFilterImpl',
-{
-  doThFilter : function(i_input,i_output,i_size,i_threshold){}
-})
-
-
-/**
- * 定数閾値による2値化をする。
- *
- */
-FLARRasterFilter_Threshold = ASKlass('FLARRasterFilter_Threshold',
-{
-  _threshold : 0
-  ,_do_threshold_impl : null
-  ,FLARRasterFilter_Threshold : function(i_threshold)
-  {
-  }
-  /**
-   * 画像を２値化するための閾値。暗点&lt;=th&lt;明点となります。
-   * @param i_threshold
-   */
-  ,setThreshold : function(i_threshold )
-  {
-    this._threshold = i_threshold;
-  }
-  ,doFilter : function(i_input, i_output)
-  {
-    NyAS3Utils.assert (i_input._width == i_output._width && i_input._height == i_output._height);
-    var out_buf = (i_output.getBuffer());
-    var in_reader = i_input.getRgbPixelReader();
-    var d = in_reader.getData().data;
-    var obd = out_buf.data;
-    var th3 = this._threshold*10000;
-    for (var i=0,j=0; i<d.length; i+=4,++j) {
-      //var c = d[i]*0.2989 + d[i+1]*0.5866 + d[i+2]*0.1145;
-      var c = d[i]*2989+d[i+1]*5866+d[i+2]*1145;
-      var t = (c <= th3) ? 0xffffffff : 0xff000000;
-      obd[j] = t;
-    }
-    if (window.DEBUG) {
-      var debugCanvas = document.getElementById('debugCanvas');
-      out_buf.drawOnCanvas(debugCanvas);
-    }
-    return;
-  }
-})
-Point = function(x,y) {
-  this.x = x||0;
-  this.y = y||0;
-}
-doThFilterImpl_BUFFERFORMAT_OBJECT_AS_BitmapData = {
-  doThFilter : function(i_input, i_output, i_threshold)
-  {
-    var out_buf = (i_output.getBuffer());
-    var in_buf= (i_input.getBuffer());
-    var d = in_buf.data;
-    var obd = out_buf.data;
-    for (var i=0; i<d.length; i++) {
-      var dc = d[i];
-      var c = ((dc>>16)&0xff)*0.2989 + ((dc>>8)&0xff)*0.5866 + (dc&0xff)*0.1145;
-      var f = (c <= i_threshold);
-      var t = f*0xffffffff + (1-f)*0xff000000;
-      obd[j] = t;
-    }
-  }
-}
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * JSARToolkit
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- *   Hirokazu Kato
- *   Mark Billinghurst
- *   HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * And the NyARToolkitAS3 ARToolKit class library.
- *   Copyright (C)2010 Ryo Iizuka
- *
- * JSARToolkit is a JavaScript port of NyARToolkitAS3.
- *   Copyright (C)2010 Ilmari Heikkinen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  ilmari.heikkinen@gmail.com
- *
- */
-
-
-/**
- * ...
- * @author
- */
-NyARLabelInfo = ASKlass('NyARLabelInfo',
-{
-  area : 0,
-  clip_r : 0,
-  clip_l : 0,
-  clip_b : 0,
-  clip_t : 0,
-  pos_x : 0,
-  pos_y : 0,
-  NyARLabelInfo : function()
-  {
-  }
-})
-
-
-//  import jp.nyatla.nyartoolkit.as3.core.types.stack.*;
-NyARLabelInfoStack = ASKlass('NyARLabelInfoStack', // NyARObjectStack,
-{
-  _items : null,
-  _length : 0,
-  NyARLabelInfoStack : function(i_length)
-  {
-    //領域確保
-    this._items = this.createArray(i_length);
-    //使用中個数をリセット
-    this._length = 0;
-    return;
-  }
-  ,createArray : function(i_length)
-  {
-    var ret= new Array(i_length);
-    for (var i =0; i < i_length; i++){
-      ret[i] = new NyARLabelInfo();
-    }
-    return (ret);
-  }
-  /**
-   * エリアの大きい順にラベルをソートします。
-   */
-  ,sortByArea : function()
-  {
-    var len=this._length;
-    if(len<1){
-      return;
-    }
-    var h = Math.floor(len * 13/10);
-    var item=this._items;
-    for(;;){
-      var swaps = 0;
-      for (var i = 0; i + h < len; i++) {
-        if (item[i + h].area > item[i].area) {
-          var temp = item[i + h];
-          item[i + h] = item[i];
-          item[i] = temp;
-          swaps++;
-        }
-      }
-      if (h == 1) {
-        if (swaps == 0){
-          break;
-        }
-      }else{
-        h=Math.floor(h*10/13);
-      }
-    }
-  }
-  /**
-   * 新しい領域を予約します。
-   * @return
-   * 失敗するとnull
-   * @throws NyARException
-   */
-  ,prePush : function()
-  {
-    // 必要に応じてアロケート
-    if (this._length >= this._items.length){
-      return null;
-    }
-    // 使用領域を+1して、予約した領域を返す。
-    var ret = this._items[this._length];
-    this._length++;
-    return ret;
-  }
-  /**
-   * スタックを初期化します。
-   * @param i_reserv_length
-   * 使用済みにするサイズ
-   * @return
-   */
-  ,init : function(i_reserv_length)
-  {
-    // 必要に応じてアロケート
-    if (i_reserv_length >= this._items.length){
-      throw new NyARException();
-    }
-    this._length=i_reserv_length;
-  }
-  /**
-   * 見かけ上の要素数を1減らして、そのオブジェクトを返します。
-   * 返却したオブジェクトの内容は、次回のpushまで有効です。
-   * @return
-   */
-  ,pop : function()
-  {
-    NyAS3Utils.assert(this._length>=1);
-    this._length--;
-    return this._items[this._length];
-  }
-  /**
-   * 見かけ上の要素数をi_count個減らします。
-   * @param i_count
-   * @return
-   */
-  ,pops : function(i_count)
-  {
-    NyAS3Utils.assert(this._length>=i_count);
-    this._length-=i_count;
-    return;
-  }
-  /**
-   * 配列を返します。
-   *
-   * @return
-   */
-  ,getArray : function()
-  {
-    return this._items;
-  }
-  ,getItem : function(i_index)
-  {
-    return this._items[i_index];
-  }
-  /**
-   * 配列の見かけ上の要素数を返却します。
-   * @return
-   */
-  ,getLength : function()
-  {
-    return this._length;
-  }
-  /**
-   * 見かけ上の要素数をリセットします。
-   */
-  ,clear : function()
-  {
-    this._length = 0;
-  }
-})
-NyARLabelOverlapChecker = ASKlass('NyARLabelOverlapChecker',
-{
-  _labels : null,
-  _length : 0,
-  /*
-  */
-  NyARLabelOverlapChecker : function(i_max_label)
-  {
-    this._labels = this.createArray(i_max_label);
-  }
-  ,createArray : function(i_length)
-  {
-    return new Array(i_length);
-  }
-  /**
-   * チェック対象のラベルを追加する。
-   *
-   * @param i_label_ref
-   */
-  ,push : function(i_label_ref)
-  {
-    this._labels[this._length] = i_label_ref;
-    this._length++;
-  }
-  /**
-   * 現在リストにあるラベルと重なっているかを返す。
-   *
-   * @param i_label
-   * @return 何れかのラベルの内側にあるならばfalse,独立したラベルである可能性が高ければtrueです．
-   */
-  ,check : function(i_label)
-  {
-    // 重なり処理かな？
-    var label_pt  = this._labels;
-    var px1 = toInt(i_label.pos_x);
-    var py1 = toInt(i_label.pos_y);
-    for (var i = this._length - 1; i >= 0; i--) {
-      var px2 = toInt(label_pt[i].pos_x);
-      var py2 = toInt(label_pt[i].pos_y);
-      var d = (px1 - px2) * (px1 - px2) + (py1 - py2) * (py1 - py2);
-      if (d < label_pt[i].area / 4) {
-        // 対象外
-        return false;
-      }
-    }
-    // 対象
-    return true;
-  }
-  /**
-   * 最大i_max_label個のラベルを蓄積できるようにオブジェクトをリセットする
-   *
-   * @param i_max_label
-   */
-  ,setMaxLabels : function(i_max_label)
-  {
-    if (i_max_label > this._labels.length) {
-      this._labels = this.createArray(i_max_label);
-    }
-    this._length = 0;
-  }
-})
-
-
-
-
-// RleImageをラベリングする。
-NyARLabeling_Rle = ASKlass('NyARLabeling_Rle',
-{
-  AR_AREA_MAX : 100000,// #define AR_AREA_MAX 100000
-  AR_AREA_MIN : 70,// #define AR_AREA_MIN 70
-  _rlestack : null,
-  _rle1 : null,
-  _rle2 : null,
-  _max_area : 0,
-  _min_area : 0,
-  NyARLabeling_Rle : function(i_width,i_height)
-  {
-    this._rlestack=new RleInfoStack(i_width*i_height*2048/(320*240)+32);
-    this._rle1 = RleElement.createArray(i_width/2+1);
-    this._rle2 = RleElement.createArray(i_width/2+1);
-    this.setAreaRange(this.AR_AREA_MAX,this.AR_AREA_MIN);
-    return;
-  }
-  /**
-   * 対象サイズ
-   * @param i_max
-   * @param i_min
-   */
-  ,setAreaRange : function(i_max,i_min)
-  {
-    this._max_area=i_max;
-    this._min_area=i_min;
-    return;
-  }
-  /**
-   * i_bin_bufのgsイメージをRLE圧縮する。
-   * @param i_bin_buf
-   * @param i_st
-   * @param i_len
-   * @param i_out
-   * @param i_th
-   * BINラスタのときは0,GSラスタの時は閾値を指定する。
-   * この関数は、閾値を暗点と認識します。
-   * 暗点<=th<明点
-   * @return
-   */
-  ,toRLE : function(i_bin_buf,i_st,i_len,i_out,i_th)
-  {
-    var current = 0;
-    var lidx=0,ridx=1,fidx=2,off=3;
-    var r = -1;
-    // 行確定開始
-    var x = i_st;
-    var right_edge = i_st + i_len - 1;
-    while (x < right_edge) {
-      // 暗点(0)スキャン
-      if (i_bin_buf[x] != 0xffffffff) {
-        x++;//明点
-        continue;
-      }
-      // 暗点発見→暗点長を調べる
-      r = (x - i_st);
-      i_out[current+lidx] = r;
-      r++;// 暗点+1
-      x++;
-      while (x < right_edge) {
-        if (i_bin_buf[x] != 0xffffffff) {
-          // 明点(1)→暗点(0)配列終了>登録
-          i_out[current+ridx] = r;
-          current+=off;
-          x++;// 次点の確認。
-          r = -1;// 右端の位置を0に。
-          break;
-        } else {
-          // 暗点(0)長追加
-          r++;
-          x++;
-        }
-      }
-    }
-    // 最後の1点だけ判定方法が少し違うの。
-    if (i_bin_buf[x] != 0xffffffff) {
-      // 明点→rカウント中なら暗点配列終了>登録
-      if (r >= 0) {
-        i_out[current+ridx] = r;
-        current+=off;
-      }
-    } else {
-      // 暗点→カウント中でなければl1で追加
-      if (r >= 0) {
-        i_out[current+ridx] = (r + 1);
-      } else {
-        // 最後の1点の場合
-        i_out[current+lidx] = (i_len - 1);
-        i_out[current+ridx] = (i_len);
-      }
-      current+=off;
-    }
-    // 行確定
-    return current/off;
-  }
-  ,addFragment : function(i_rel_img,i_img_idx,i_nof,i_row_index,o_stack)
-  {
-    var lidx=0,ridx=1,fidx=2,off=3;
-    var l = i_rel_img[i_img_idx+lidx];
-    var r = i_rel_img[i_img_idx+ridx];
-    var len=r - l;
-    i_rel_img[i_img_idx+fidx] = i_nof;// REL毎の固有ID
-    var v = o_stack.prePush();
-    v.entry_x = l;
-    v.area =len;
-    v.clip_l=l;
-    v.clip_r=r-1;
-    v.clip_t=i_row_index;
-    v.clip_b=i_row_index;
-    v.pos_x=(len*(2*l+(len-1)))/2;
-    v.pos_y=i_row_index*len;
-    return;
-  }
-  //所望のラスタからBIN-RLEに変換しながらの低速系も準備しようかな
-  /**
-   * 単一閾値を使ってGSラスタをBINラスタに変換しながらラベリングします。
-   * @param i_gs_raster
-   * @param i_top
-   * @param i_bottom
-   * @param o_stack
-   * @return
-   * @throws NyARException
-   */
-  ,labeling_NyARBinRaster : function(i_bin_raster,i_top,i_bottom,o_stack)
-  {
-    NyAS3Utils.assert(i_bin_raster.isEqualBufferType(NyARBufferType.INT1D_BIN_8));
-    return this.imple_labeling(i_bin_raster,0,i_top,i_bottom,o_stack);
-  }
-  /**
-   * BINラスタをラベリングします。
-   * @param i_gs_raster
-   * @param i_th
-   * 画像を２値化するための閾値。暗点&lt;=th&lt;明点となります。
-   * @param i_top
-   * @param i_bottom
-   * @param o_stack
-   * @return
-   * @throws NyARException
-   */
-  ,labeling_NyARGrayscaleRaster : function(i_gs_raster,i_th,i_top,i_bottom,o_stack)
-  {
-    NyAS3Utils.assert(i_gs_raster.isEqualBufferType(NyARBufferType.INT1D_GRAY_8));
-    return this.imple_labeling(i_gs_raster,i_th,i_top,i_bottom,o_stack);
-  }
-  ,labeling : function(i_bin_raster,o_stack)
-  {
-    return this.imple_labeling(i_bin_raster,0,0,i_bin_raster.getHeight(),o_stack);
-  }
-  ,imple_labeling : function(i_raster,i_th,i_top,i_bottom,o_stack)
-  {
-    // リセット処理
-    var rlestack=this._rlestack;
-    rlestack.clear();
-    //
-    var rle_prev = this._rle1;
-    var rle_current = this._rle2;
-    var len_prev = 0;
-    var len_current = 0;
-    var width = i_raster.getWidth();
-    var in_buf = (i_raster.getBuffer().data);
-    var id_max = 0;
-    var label_count=0;
-    var lidx=0,ridx=1,fidx=2,off=3;
-    // 初段登録
-    len_prev = this.toRLE(in_buf, i_top, width, rle_prev, i_th);
-    var i;
-    for (i = 0; i < len_prev; i++) {
-      // フラグメントID=フラグメント初期値、POS=Y値、RELインデクス=行
-      this.addFragment(rle_prev, i*off, id_max, i_top,rlestack);
-      id_max++;
-      // nofの最大値チェック
-      label_count++;
-    }
-    var f_array = (rlestack.getArray());
-    // 次段結合
-    for (var y = i_top + 1; y < i_bottom; y++) {
-      // カレント行の読込
-      len_current = this.toRLE(in_buf, y * width, width, rle_current,i_th);
-      var index_prev = 0;
-      SCAN_CUR: for (i = 0; i < len_current; i++) {
-        // index_prev,len_prevの位置を調整する
-        var id = -1;
-        // チェックすべきprevがあれば確認
-        SCAN_PREV: while (index_prev < len_prev) {
-          if (rle_current[i*off+lidx] - rle_prev[index_prev*off+ridx] > 0) {// 0なら8方位ラベリング
-            // prevがcurの左方にある→次のフラグメントを探索
-            index_prev++;
-            continue;
-          } else if (rle_prev[index_prev*off+lidx] - rle_current[i*off+ridx] > 0) {// 0なら8方位ラベリングになる
-            // prevがcur右方にある→独立フラグメント
-            this.addFragment(rle_current, i*off, id_max, y,rlestack);
-            id_max++;
-            label_count++;
-            // 次のindexをしらべる
-            continue SCAN_CUR;
-          }
-          id=rle_prev[index_prev*off+fidx];//ルートフラグメントid
-          var id_ptr = f_array[id];
-          //結合対象(初回)->prevのIDをコピーして、ルートフラグメントの情報を更新
-          rle_current[i*off+fidx] = id;//フラグメントIDを保存
-          //
-          var l= rle_current[i*off+lidx];
-          var r= rle_current[i*off+ridx];
-          var len=r-l;
-          //結合先フラグメントの情報を更新する。
-          id_ptr.area += len;
-          //tとentry_xは、結合先のを使うので更新しない。
-          id_ptr.clip_l=l<id_ptr.clip_l?l:id_ptr.clip_l;
-          id_ptr.clip_r=r>id_ptr.clip_r?r-1:id_ptr.clip_r;
-          id_ptr.clip_b=y;
-          id_ptr.pos_x+=(len*(2*l+(len-1)))/2;
-          id_ptr.pos_y+=y*len;
-          //多重結合の確認（２個目以降）
-          index_prev++;
-          while (index_prev < len_prev) {
-            if (rle_current[i*off+lidx] - rle_prev[index_prev*off+ridx] > 0) {// 0なら8方位ラベリング
-              // prevがcurの左方にある→prevはcurに連結していない。
-              break SCAN_PREV;
-            } else if (rle_prev[index_prev*off+lidx] - rle_current[i*off+ridx] > 0) {// 0なら8方位ラベリングになる
-              // prevがcurの右方にある→prevはcurに連結していない。
-              index_prev--;
-              continue SCAN_CUR;
-            }
-            // prevとcurは連結している→ルートフラグメントの統合
-            //結合するルートフラグメントを取得
-            var prev_id =rle_prev[index_prev*off+fidx];
-            var prev_ptr = f_array[prev_id];
-            if (id != prev_id){
-              label_count--;
-              //prevとcurrentのフラグメントidを書き換える。
-              var i2;
-              for(i2=index_prev;i2<len_prev;i2++){
-                //prevは現在のidから最後まで
-                if(rle_prev[i2*off+fidx]==prev_id){
-                  rle_prev[i2*off+fidx]=id;
-                }
-              }
-              for(i2=0;i2<i;i2++){
-                //currentは0から現在-1まで
-                if(rle_current[i2*off+fidx]==prev_id){
-                  rle_current[i2*off+fidx]=id;
-                }
-              }
-              //現在のルートフラグメントに情報を集約
-              id_ptr.area +=prev_ptr.area;
-              id_ptr.pos_x+=prev_ptr.pos_x;
-              id_ptr.pos_y+=prev_ptr.pos_y;
-              //tとentry_xの決定
-              if (id_ptr.clip_t > prev_ptr.clip_t) {
-                // 現在の方が下にある。
-                id_ptr.clip_t = prev_ptr.clip_t;
-                id_ptr.entry_x = prev_ptr.entry_x;
-              }else if (id_ptr.clip_t < prev_ptr.clip_t) {
-                // 現在の方が上にある。prevにフィードバック
-              } else {
-                // 水平方向で小さい方がエントリポイント。
-                if (id_ptr.entry_x > prev_ptr.entry_x) {
-                  id_ptr.entry_x = prev_ptr.entry_x;
-                }else{
-                }
-              }
-              //lの決定
-              if (id_ptr.clip_l > prev_ptr.clip_l) {
-                id_ptr.clip_l=prev_ptr.clip_l;
-              }else{
-              }
-              //rの決定
-              if (id_ptr.clip_r < prev_ptr.clip_r) {
-                id_ptr.clip_r=prev_ptr.clip_r;
-              }else{
-              }
-              //bの決定
-              //結合済のルートフラグメントを無効化する。
-              prev_ptr.area=0;
-            }
-            index_prev++;
-          }
-          index_prev--;
-          break;
-        }
-        // curにidが割り当てられたかを確認
-        // 右端独立フラグメントを追加
-        if (id < 0){
-          this.addFragment(rle_current, i*off, id_max, y,rlestack);
-          id_max++;
-          label_count++;
-        }
-      }
-      // prevとrelの交換
-      var tmp = rle_prev;
-      rle_prev = rle_current;
-      len_prev = len_current;
-      rle_current = tmp;
-    }
-    //対象のラベルだけ転写
-    o_stack.init(label_count);
-    var o_dest_array=(o_stack.getArray());
-    var max=this._max_area;
-    var min=this._min_area;
-    var active_labels=0;
-    for(i=id_max-1;i>=0;i--){
-      var area=f_array[i].area;
-      if(area<min || area>max){//対象外のエリア0のもminではじく
-        continue;
-      }
-      //
-      var src_info=f_array[i];
-      var dest_info=o_dest_array[active_labels];
-      dest_info.area=area;
-      dest_info.clip_b=src_info.clip_b;
-      dest_info.clip_r=src_info.clip_r;
-      dest_info.clip_t=src_info.clip_t;
-      dest_info.clip_l=src_info.clip_l;
-      dest_info.entry_x=src_info.entry_x;
-      dest_info.pos_x=src_info.pos_x/src_info.area;
-      dest_info.pos_y=src_info.pos_y/src_info.area;
-      active_labels++;
-    }
-    //ラベル数を再設定
-    o_stack.pops(label_count-active_labels);
-    //ラベル数を返却
-    return active_labels;
-  }
-})
-RleInfo = ASKlass('RleInfo',
-{
-//継承メンバ
-entry_x : 0, // フラグメントラベルの位置
-area : 0,
-clip_r : 0,
-clip_l : 0,
-clip_b : 0,
-clip_t : 0,
-pos_x : 0,
-pos_y : 0
-})
-
-RleInfoStack = ASKlass('RleInfoStack', NyARObjectStack,
-{
-  RleInfoStack : function(i_length)
-  {
-    NyARObjectStack.initialize.call(this,i_length);
-    return;
-  }
-  ,createArray : function(i_length)
-  {
-    var ret= new Array(toInt(i_length));
-    for (var i =0; i < i_length; i++){
-      ret[i] = new RleInfo();
-    }
-    return ret;
-  }
-})
-RleElement = ASKlass('RleElement',
-{
-  l : 0,
-  r : 0,
-  fid : 0,
-  createArray : function(i_length)
-  {
-    return new IntVector(toInt(i_length)*3);
-    var ret = new Array(toInt(i_length));
-    for (var i = 0; i < i_length; i++) {
-      ret[i] = new RleElement();
-    }
-    return ret;
-  }
-})
-NyARRleLabelFragmentInfo = ASKlass('NyARRleLabelFragmentInfo', NyARLabelInfo,
-{
-  //継承メンバ
-  //int area; // フラグメントラベルの領域数
-  entry_x : 0 // フラグメントラベルの位置
-})
-NyARRleLabelFragmentInfoStack = ASKlass('NyARRleLabelFragmentInfoStack',  NyARLabelInfoStack,
-{
-  NyARRleLabelFragmentInfoStack : function(i_length)
-  {
-    NyARLabelInfoStack.initialize.call(this,i_length);
-    return;
-  }
-  ,createArray : function(i_length)
-  {
-    var ret= new Array(toInt(i_length));
-    for (var i =0; i < i_length; i++){
-      ret[i] = new NyARRleLabelFragmentInfo();
-    }
-    return (ret);
-  }
-})
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * JSARToolkit
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- *   Hirokazu Kato
- *   Mark Billinghurst
- *   HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * And the NyARToolkitAS3 ARToolKit class library.
- *   Copyright (C)2010 Ryo Iizuka
- *
- * JSARToolkit is a JavaScript port of NyARToolkitAS3.
- *   Copyright (C)2010 Ilmari Heikkinen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  ilmari.heikkinen@gmail.com
- *
- */
-INyARCameraDistortionFactor = ASKlass('INyARCameraDistortionFactor',
-{
-  ideal2Observ : function(i_in,o_out){},
-  ideal2ObservBatch : function(i_in,o_out,i_size){},
-  observ2Ideal : function(ix,iy,o_point){},
-  observ2IdealBatch : function(i_x_coord,i_y_coord,i_start,i_num,o_x_coord,o_y_coord){}
-})
-
-/**
- * カメラの歪み成分を格納するクラスと、補正関数群
- * http://www.hitl.washington.edu/artoolkit/Papers/ART02-Tutorial.pdf
- * 11ページを読むといいよ。
- *
- * x=x(xi-x0),y=s(yi-y0)
- * d^2=x^2+y^2
- * p=(1-fd^2)
- * xd=px+x0,yd=py+y0
- */
-NyARCameraDistortionFactor = ASKlass('NyARCameraDistortionFactor', INyARCameraDistortionFactor,
-{
-  PD_LOOP : 3,
-  _f0 : 0,//x0
-  _f1 : 0,//y0
-  _f2 : 0,//100000000.0*ｆ
-  _f3 : 0,//s
-  copyFrom : function(i_ref)
-  {
-    this._f0=i_ref._f0;
-    this._f1=i_ref._f1;
-    this._f2=i_ref._f2;
-    this._f3=i_ref._f3;
-    return;
-  }
-  /**
-   * 配列の値をファクタ値としてセットする。
-   * @param i_factor
-   * 4要素以上の配列
-   */
-  ,setValue : function(i_factor)
-  {
-    this._f0=i_factor[0];
-    this._f1=i_factor[1];
-    this._f2=i_factor[2];
-    this._f3=i_factor[3];
-    return;
-  }
-  ,getValue : function(o_factor)
-  {
-    o_factor[0]=this._f0;
-    o_factor[1]=this._f1;
-    o_factor[2]=this._f2;
-    o_factor[3]=this._f3;
-    return;
-  }
-  ,changeScale : function(i_scale)
-  {
-    this._f0=this._f0*i_scale;// newparam->dist_factor[0] =source->dist_factor[0] *scale;
-    this._f1=this._f1*i_scale;// newparam->dist_factor[1] =source->dist_factor[1] *scale;
-    this._f2=this._f2/ (i_scale * i_scale);// newparam->dist_factor[2]=source->dist_factor[2]/ (scale*scale);
-    //this.f3=this.f3;// newparam->dist_factor[3] =source->dist_factor[3];
-    return;
-  }
-  /**
-   * int arParamIdeal2Observ( const double dist_factor[4], const double ix,const double iy,double *ox, double *oy ) 関数の代替関数
-   *
-   * @param i_in
-   * @param o_out
-   */
-  ,ideal2Observ : function(i_in,o_out)
-  {
-    var x = (i_in.x - this._f0) * this._f3;
-    var y = (i_in.y - this._f1) * this._f3;
-    if (x == 0.0 && y == 0.0) {
-      o_out.x = this._f0;
-      o_out.y = this._f1;
-    } else {
-      var d = 1.0 - this._f2 / 100000000.0 * (x * x + y * y);
-      o_out.x = x * d + this._f0;
-      o_out.y = y * d + this._f1;
-    }
-    return;
-  }
-  /**
-   * ideal2Observをまとめて実行します。
-   * @param i_in
-   * @param o_out
-   */
-  ,ideal2ObservBatch : function(i_in, o_out ,i_size)
-  {
-    var x, y;
-    var d0 = this._f0;
-    var d1 = this._f1;
-    var d3 = this._f3;
-    var d2_w = this._f2 / 100000000.0;
-    for (var i = 0; i < i_size; i++) {
-      x = (i_in[i].x - d0) * d3;
-      y = (i_in[i].y - d1) * d3;
-      if (x == 0.0 && y == 0.0) {
-        o_out[i].x = d0;
-        o_out[i].y = d1;
-      } else {
-        var d = 1.0 - d2_w * (x * x + y * y);
-        o_out[i].x = x * d + d0;
-        o_out[i].y = y * d + d1;
-      }
-    }
-    return;
-  }
-  /**
-   * int arParamObserv2Ideal( const double dist_factor[4], const double ox,const double oy,double *ix, double *iy );
-   *
-   * @param ix
-   * @param iy
-   * @param ix
-   * @param iy
-   * @return
-   */
-  ,observ2Ideal : function(ix, iy, o_point)
-  {
-    var z02, z0, p, q, z, px, py, opttmp_1;
-    var d0 = this._f0;
-    var d1 = this._f1;
-    px = ix - d0;
-    py = iy - d1;
-    p = this._f2 / 100000000.0;
-    z02 = px * px + py * py;
-    q = z0 = Math.sqrt(z02);// Optimize//q = z0 = Math.sqrt(px*px+ py*py);
-    for (var i = 1;; i++) {
-      if (z0 != 0.0) {
-        // Optimize opttmp_1
-        opttmp_1 = p * z02;
-        z = z0 - ((1.0 - opttmp_1) * z0 - q) / (1.0 - 3.0 * opttmp_1);
-        px = px * z / z0;
-        py = py * z / z0;
-      } else {
-        px = 0.0;
-        py = 0.0;
-        break;
-      }
-      if (i == this.PD_LOOP) {
-        break;
-      }
-      z02 = px * px + py * py;
-      z0 = Math.sqrt(z02);// Optimize//z0 = Math.sqrt(px*px+ py*py);
-    }
-    o_point.x = px / this._f3 + d0;
-    o_point.y = py / this._f3 + d1;
-    return;
-  }
-  /**
-   * 指定範囲のobserv2Idealをまとめて実行して、結果をo_idealに格納します。
-   * @param i_x_coord
-   * @param i_y_coord
-   * @param i_start
-   *            coord開始点
-   * @param i_num
-   *            計算数
-   * @param o_ideal
-   *            出力バッファ[i_num][2]であること。
-   */
-  ,observ2IdealBatch : function(i_x_coord,i_y_coord,i_start,i_num,o_x_coord,o_y_coord)
-  {
-    var z02, z0, q, z, px, py, opttmp_1;
-    var d0 = this._f0;
-    var d1 = this._f1;
-    var d3 = this._f3;
-    var p = this._f2 / 100000000.0;
-    for (var j = 0; j < i_num; j++) {
-      px = i_x_coord[i_start + j] - d0;
-      py = i_y_coord[i_start + j] - d1;
-      z02 = px * px + py * py;
-      q = z0 = Math.sqrt(z02);// Optimize//q = z0 = Math.sqrt(px*px+py*py);
-      for (var i = 1;; i++) {
-        if (z0 != 0.0) {
-          // Optimize opttmp_1
-          opttmp_1 = p * z02;
-          z = z0 - ((1.0 - opttmp_1) * z0 - q)/ (1.0 - 3.0 * opttmp_1);
-          px = px * z / z0;
-          py = py * z / z0;
-        } else {
-          px = 0.0;
-          py = 0.0;
-          break;
-        }
-        if (i == PD_LOOP) {
-          break;
-        }
-        z02 = px * px + py * py;
-        z0 = Math.sqrt(z02);// Optimize//z0 = Math.sqrt(px*px+ py*py);
-      }
-      o_x_coord[j] = px / d3 + d0;
-      o_y_coord[j] = py / d3 + d1;
-    }
-    return;
-  }
-})
-NyARObserv2IdealMap = ASKlass('NyARObserv2IdealMap',
-{
-  _stride : 0,
-  _mapx : null,
-  _mapy : null,
-  NyARObserv2IdealMap : function(i_distfactor,i_screen_size)
-  {
-    var opoint=new NyARDoublePoint2d();
-    this._mapx=new FloatVector(i_screen_size.w*i_screen_size.h);
-    this._mapy=new FloatVector(i_screen_size.w*i_screen_size.h);
-    this._stride=i_screen_size.w;
-    var ptr=i_screen_size.h*i_screen_size.w-1;
-    //歪みマップを構築
-    for(var i=i_screen_size.h-1;i>=0;i--)
-    {
-      for(var i2=i_screen_size.w-1;i2>=0;i2--)
-      {
-        i_distfactor.observ2Ideal(i2,i, opoint);
-        this._mapx[ptr]=opoint.x;
-        this._mapy[ptr]=opoint.y;
-        ptr--;
-      }
-    }
-    return;
-  }
-  ,observ2Ideal : function(ix,iy,o_point)
-  {
-    var idx=ix+iy*this._stride;
-    o_point.x=this._mapx[idx];
-    o_point.y=this._mapy[idx];
-    return;
-  }
-  ,observ2IdealBatch : function(i_x_coord,i_y_coord,i_start,i_num,o_x_coord,o_y_coord,i_out_start_index)
-  {
-    var idx;
-    var ptr=i_out_start_index;
-    var mapx=this._mapx;
-    var mapy=this._mapy;
-    var stride=this._stride;
-    for (var j = 0; j < i_num; j++){
-      idx=i_x_coord[i_start + j]+i_y_coord[i_start + j]*stride;
-      o_x_coord[ptr]=mapx[idx];
-      o_y_coord[ptr]=mapy[idx];
-      ptr++;
-    }
-    return;
-  }
-})
-
-NyARPerspectiveProjectionMatrix = ASKlass('NyARPerspectiveProjectionMatrix', NyARDoubleMatrix34,
-{
-  /*
-   * static double dot( double a1, double a2, double a3,double b1, double b2,double b3 )
-   */
-  dot : function(a1,a2,a3,b1,b2,b3)
-  {
-    return (a1 * b1 + a2 * b2 + a3 * b3);
-  }
-  /* static double norm( double a, double b, double c ) */
-  ,norm : function(a,b,c)
-  {
-    return Math.sqrt(a * a + b * b + c * c);
-  }
-  /**
-   * int arParamDecompMat( double source[3][4], double cpara[3][4], double trans[3][4] ); 関数の置き換え Optimize STEP[754->665]
-   *
-   * @param o_cpara
-   *            戻り引数。3x4のマトリクスを指定すること。
-   * @param o_trans
-   *            戻り引数。3x4のマトリクスを指定すること。
-   * @return
-   */
-  ,decompMat : function(o_cpara,o_trans)
-  {
-    var r, c;
-    var rem1, rem2, rem3;
-    var c00,c01,c02,c03,c10,c11,c12,c13,c20,c21,c22,c23;
-    if (this.m23>= 0) {// if( source[2][3] >= 0 ) {
-      // <Optimize>
-      // for(int r = 0; r < 3; r++ ){
-      // for(int c = 0; c < 4; c++ ){
-      // Cpara[r][c]=source[r][c];//Cpara[r][c] = source[r][c];
-      // }
-      // }
-      c00=this.m00;
-      c01=this.m01;
-      c02=this.m02;
-      c03=this.m03;
-      c10=this.m10;
-      c11=this.m11;
-      c12=this.m12;
-      c13=this.m13;
-      c20=this.m20;
-      c21=this.m21;
-      c22=this.m22;
-      c23=this.m23;
-    } else {
-      // <Optimize>
-      // for(int r = 0; r < 3; r++ ){
-      // for(int c = 0; c < 4; c++ ){
-      // Cpara[r][c]=-source[r][c];//Cpara[r][c] = -(source[r][c]);
-      // }
-      // }
-      c00=-this.m00;
-      c01=-this.m01;
-      c02=-this.m02;
-      c03=-this.m03;
-      c10=-this.m10;
-      c11=-this.m11;
-      c12=-this.m12;
-      c13=-this.m13;
-      c20=-this.m20;
-      c21=-this.m21;
-      c22=-this.m22;
-      c23=-this.m23;
-    }
-    var cpara= o_cpara.getArray();
-    var trans= o_trans.getArray();
-    for (r = 0; r < 3; r++) {
-      for (c = 0; c < 4; c++) {
-        cpara[r][c] = 0.0;// cpara[r][c] = 0.0;
-      }
-    }
-    cpara[2][2] = this.norm(c20, c21, c22);// cpara[2][2] =norm( Cpara[2][0],Cpara[2][1],Cpara[2][2]);
-    trans[2][0] = c20 / cpara[2][2];// trans[2][0] = Cpara[2][0] /cpara[2][2];
-    trans[2][1] = c21 / cpara[2][2];// trans[2][1] = Cpara[2][1] / cpara[2][2];
-    trans[2][2] = c22 / cpara[2][2];// trans[2][2] =Cpara[2][2] /cpara[2][2];
-    trans[2][3] = c23 / cpara[2][2];// trans[2][3] =Cpara[2][3] /cpara[2][2];
-    cpara[1][2] = this.dot(trans[2][0], trans[2][1], trans[2][2], c10, c11, c12);// cpara[1][2]=dot(trans[2][0],trans[2][1],trans[2][2],Cpara[1][0],Cpara[1][1],Cpara[1][2]);
-    rem1 = c10 - cpara[1][2] * trans[2][0];// rem1 =Cpara[1][0] -cpara[1][2] *trans[2][0];
-    rem2 = c11 - cpara[1][2] * trans[2][1];// rem2 =Cpara[1][1] -cpara[1][2] *trans[2][1];
-    rem3 = c12 - cpara[1][2] * trans[2][2];// rem3 =Cpara[1][2] -cpara[1][2] *trans[2][2];
-    cpara[1][1] = this.norm(rem1, rem2, rem3);// cpara[1][1] = norm( rem1,// rem2, rem3 );
-    trans[1][0] = rem1 / cpara[1][1];// trans[1][0] = rem1 / cpara[1][1];
-    trans[1][1] = rem2 / cpara[1][1];// trans[1][1] = rem2 / cpara[1][1];
-    trans[1][2] = rem3 / cpara[1][1];// trans[1][2] = rem3 / cpara[1][1];
-    cpara[0][2] = this.dot(trans[2][0], trans[2][1], trans[2][2], c00, c01, c02);// cpara[0][2] =dot(trans[2][0], trans[2][1],trans[2][2],Cpara[0][0],Cpara[0][1],Cpara[0][2]);
-    cpara[0][1] = this.dot(trans[1][0], trans[1][1], trans[1][2], c00, c01, c02);// cpara[0][1]=dot(trans[1][0],trans[1][1],trans[1][2],Cpara[0][0],Cpara[0][1],Cpara[0][2]);
-    rem1 = c00 - cpara[0][1] * trans[1][0] - cpara[0][2]* trans[2][0];// rem1 = Cpara[0][0] - cpara[0][1]*trans[1][0]- cpara[0][2]*trans[2][0];
-    rem2 = c01 - cpara[0][1] * trans[1][1] - cpara[0][2]* trans[2][1];// rem2 = Cpara[0][1] - cpara[0][1]*trans[1][1]- cpara[0][2]*trans[2][1];
-    rem3 = c02 - cpara[0][1] * trans[1][2] - cpara[0][2]* trans[2][2];// rem3 = Cpara[0][2] - cpara[0][1]*trans[1][2] - cpara[0][2]*trans[2][2];
-    cpara[0][0] = this.norm(rem1, rem2, rem3);// cpara[0][0] = norm( rem1,rem2, rem3 );
-    trans[0][0] = rem1 / cpara[0][0];// trans[0][0] = rem1 / cpara[0][0];
-    trans[0][1] = rem2 / cpara[0][0];// trans[0][1] = rem2 / cpara[0][0];
-    trans[0][2] = rem3 / cpara[0][0];// trans[0][2] = rem3 / cpara[0][0];
-    trans[1][3] = (c13 - cpara[1][2] * trans[2][3])/ cpara[1][1];// trans[1][3] = (Cpara[1][3] -cpara[1][2]*trans[2][3]) / cpara[1][1];
-    trans[0][3] = (c03 - cpara[0][1] * trans[1][3] - cpara[0][2]* trans[2][3])/ cpara[0][0];// trans[0][3] = (Cpara[0][3] -cpara[0][1]*trans[1][3]-cpara[0][2]*trans[2][3]) / cpara[0][0];
-    for (r = 0; r < 3; r++) {
-      for (c = 0; c < 3; c++) {
-        cpara[r][c] /= cpara[2][2];// cpara[r][c] /= cpara[2][2];
-      }
-    }
-    return;
-  }
-  /**
-   * int arParamChangeSize( ARParam *source, int xsize, int ysize, ARParam *newparam );
-   * Matrixのスケールを変換します。
-   * @param i_scale
-   *
-   */
-  ,changeScale : function(i_scale)
-  {
-    this.m00=this.m00*i_scale;
-    this.m10=this.m10*i_scale;
-    this.m01=this.m01*i_scale;
-    this.m11=this.m11*i_scale;
-    this.m02=this.m02*i_scale;
-    this.m12=this.m12*i_scale;
-    this.m03=this.m03*i_scale;
-    this.m13=this.m13*i_scale;
-    //for (int i = 0; i < 4; i++) {
-    //  array34[0 * 4 + i] = array34[0 * 4 + i] * scale;// newparam->mat[0][i]=source->mat[0][i]* scale;
-    //  array34[1 * 4 + i] = array34[1 * 4 + i] * scale;// newparam->mat[1][i]=source->mat[1][i]* scale;
-    //  array34[2 * 4 + i] = array34[2 * 4 + i];// newparam->mat[2][i] = source->mat[2][i];
-    //}
-    return;
-  }
-  /**
-   * 現在の行列で３次元座標を射影変換します。
-   * @param i_3dvertex
-   * @param o_2d
-   */
-  ,projectionConvert_NyARDoublePoint3d : function(i_3dvertex,o_2d)
-  {
-    var w=i_3dvertex.z*this.m22;
-    o_2d.x=(i_3dvertex.x*this.m00+i_3dvertex.y*this.m01+i_3dvertex.z*this.m02)/w;
-    o_2d.y=(i_3dvertex.y*this.m11+i_3dvertex.z*this.m12)/w;
-    return;
-  }
-  ,projectionConvert_Number : function(i_x,i_y,i_z,o_2d)
-  {
-    var w=i_z*this.m22;
-    o_2d.x=(i_x*this.m00+i_y*this.m01+i_z*this.m02)/w;
-    o_2d.y=(i_y*this.m11+i_z*this.m12)/w;
-    return;
-  }
-})
-
-
-/**
- * typedef struct { int xsize, ysize; double mat[3][4]; double dist_factor[4]; } ARParam;
- * NyARの動作パラメータを格納するクラス
- *
- */
-NyARParam = ASKlass('NyARParam',
-{
-  _screen_size : new NyARIntSize(),
-  SIZE_OF_PARAM_SET : 4 + 4 + (3 * 4 * 8) + (4 * 8),
-  _dist : new NyARCameraDistortionFactor(),
-  _projection_matrix : new NyARPerspectiveProjectionMatrix(),
-  getScreenSize : function()
-  {
-    return this._screen_size;
-  }
-  ,getPerspectiveProjectionMatrix : function()
-  {
-    return this._projection_matrix;
-  }
-  ,getDistortionFactor : function()
-  {
-    return this._dist;
-  }
-  /**
-   * Copy the perspective projection matrix to the given m_projection FloatVector GL camera matrix.
-   */
-  ,copyCameraMatrix : function(m_projection, NEAR_CLIP, FAR_CLIP) {
-    var trans_mat = new FLARMat(3,4);
-    var icpara_mat = new FLARMat(3,4);
-    var p = ArrayUtil.createJaggedArray(3, 3);
-    var q = ArrayUtil.createJaggedArray(4, 4);
-    var i = 0;
-    var j = 0;
-    var size = this.getScreenSize();
-    var  width = size.w;
-    var height = size.h;
-
-    this.getPerspectiveProjectionMatrix().decompMat(icpara_mat, trans_mat);
-
-    var icpara = icpara_mat.getArray();
-    var trans = trans_mat.getArray();
-    for (i = 0; i < 4; i++) {
-      icpara[1][i] = (height - 1) * (icpara[2][i]) - icpara[1][i];
-    }
-
-    for(i = 0; i < 3; i++) {
-      for(j = 0; j < 3; j++) {
-        p[i][j] = icpara[i][j] / icpara[2][2];
-      }
-    }
-    q[0][0] = (2.0 * p[0][0] / (width - 1));
-    q[0][1] = (2.0 * p[0][1] / (width - 1));
-    q[0][2] = -((2.0 * p[0][2] / (width - 1))  - 1.0);
-    q[0][3] = 0.0;
-
-    q[1][0] = 0.0;
-    q[1][1] = -(2.0 * p[1][1] / (height - 1));
-    q[1][2] = -((2.0 * p[1][2] / (height - 1)) - 1.0);
-    q[1][3] = 0.0;
-
-    q[2][0] = 0.0;
-    q[2][1] = 0.0;
-    q[2][2] = -(FAR_CLIP + NEAR_CLIP) / (NEAR_CLIP - FAR_CLIP);
-    q[2][3] = 2.0 * FAR_CLIP * NEAR_CLIP / (NEAR_CLIP - FAR_CLIP);
-
-    q[3][0] = 0.0;
-    q[3][1] = 0.0;
-    q[3][2] = 1.0;
-    q[3][3] = 0.0;
-
-    for (i = 0; i < 4; i++) { // Row.
-      // First 3 columns of the current row.
-      for (j = 0; j < 3; j++) { // Column.
-        m_projection[j*4 + i] =
-          q[i][0] * trans[0][j] +
-          q[i][1] * trans[1][j] +
-          q[i][2] * trans[2][j];
-      }
-      // Fourth column of the current row.
-      m_projection[i+4*3]=
-        q[i][0] * trans[0][3] +
-        q[i][1] * trans[1][3] +
-        q[i][2] * trans[2][3] +
-        q[i][3];
-    }
-  }
-  /**
-   *
-   * @param i_factor
-   * NyARCameraDistortionFactorにセットする配列を指定する。要素数は4であること。
-   * @param i_projection
-   * NyARPerspectiveProjectionMatrixセットする配列を指定する。要素数は12であること。
-   */
-  ,setValue : function(i_factor,i_projection)
-  {
-    this._dist.setValue(i_factor);
-    this._projection_matrix.setValue(i_projection);
-    return;
-  }
-  /**
-   * int arParamChangeSize( ARParam *source, int xsize, int ysize, ARParam *newparam );
-   * 関数の代替関数 サイズプロパティをi_xsize,i_ysizeに変更します。
-   * @param i_xsize
-   * @param i_ysize
-   * @param newparam
-   * @return
-   *
-   */
-  ,changeScreenSize : function(i_xsize,i_ysize)
-  {
-    var scale = i_xsize / this._screen_size.w;// scale = (double)xsize / (double)(source->xsize);
-    //スケールを変更
-    this._dist.changeScale(scale);
-    this._projection_matrix.changeScale(scale);
-    this._screen_size.w = i_xsize;// newparam->xsize = xsize;
-    this._screen_size.h = i_ysize;// newparam->ysize = ysize;
-    return;
-  }
-  ,loadARParam : function(i_stream)
-  {
-    var tmp = new FloatVector(12);//new double[12];
-    i_stream.endian = Endian.BIG_ENDIAN;
-    this._screen_size.w = i_stream.readInt();//bb.getInt();
-    this._screen_size.h = i_stream.readInt();//bb.getInt();
-    //double値を12個読み込む
-    var i;
-    for(i = 0; i < 12; i++){
-      tmp[i] = i_stream.readDouble();//bb.getDouble();
-    }
-    //Projectionオブジェクトにセット
-    this._projection_matrix.setValue(tmp);
-    //double値を4個読み込む
-    for (i = 0; i < 4; i++) {
-      tmp[i] = i_stream.readDouble();//bb.getDouble();
-    }
-    //Factorオブジェクトにセット
-    this._dist.setValue(tmp);
-    return;
-  }
-})
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * PROJECT: FLARToolKit
- * --------------------------------------------------------------------------------
- * This work is based on the NyARToolKit developed by
- *   R.Iizuka (nyatla)
- * http://nyatla.jp/nyatoolkit/
- *
- * The FLARToolKit is ActionScript 3.0 version ARToolkit class library.
- * Copyright (C)2008 Saqoosha
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  http://www.libspark.org/wiki/saqoosha/FLARToolKit
- *  <saq(at)saqoosha.net>
- *
- */
-
-/**
- * typedef struct { int xsize, ysize; double mat[3][4]; double dist_factor[4]; } ARParam;
- * NyARの動作パラメータを格納するクラス
- *
- * @see jp.nyatla.nyartoolkit.as3.core.param.NyARParam
- */
-FLARParam = ASKlass('FLARParam', NyARParam,
-{
-  FLARParam : function(w,h,vfov)
-  {
-    w = w || 640;
-    h = h || 480;
-    this._screen_size.w = w;
-    this._screen_size.h = h;
-    var dist, projection;
-    if (vfov) {
-        //8 Sep 2013, Skeel Lee (skeel@skeelogy.com)
-        //Removed hardcoded values in projection matrix so that it can work more generically
-        var hf = h/(2*Math.tan(Math.PI/180*vfov/2.0));
-        dist = new FloatVector([w/2, h/2, 0, 1]);
-        projection = new FloatVector([hf, 0, w/2, 0,
-                                      0, hf, h/2, 0,
-                                      0, 0, 1, 0]);
-    } else {
-        //Keep the originals so that existing codes/looks will not break
-        var f = (w/h) / (4/3);
-        dist = new FloatVector([w/2, 1.1*h/2, 26.2, 1.0127565206658486]);
-        projection = new FloatVector([f*700.9514702992245, 0, w/2-0.5, 0,
-                                      0, 726.0941816535367, h/2-0.5, 0,
-                                      0, 0,                 1,     0]);
-    }
-    this.setValue(dist, projection);
-  }
-
-})
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * JSARToolkit
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- *   Hirokazu Kato
- *   Mark Billinghurst
- *   HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * And the NyARToolkitAS3 ARToolKit class library.
- *   Copyright (C)2010 Ryo Iizuka
- *
- * JSARToolkit is a JavaScript port of NyARToolkitAS3.
- *   Copyright (C)2010 Ilmari Heikkinen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  ilmari.heikkinen@gmail.com
- *
- */
-
-INyARRaster = ASKlass('INyARRaster',
-{
-  getWidth : function(){},
-  getHeight : function(){},
-  getSize : function(){},
-  /**
-   * バッファオブジェクトを返します。
-   * @return
-   */
-  getBuffer : function(){},
-  /**
-   * バッファオブジェクトのタイプを返します。
-   * @return
-   */
-  getBufferType : function(){},
-  /**
-   * バッファのタイプがi_type_valueであるか、チェックします。
-   * この値は、NyARBufferTypeに定義された定数値です。
-   * @param i_type_value
-   * @return
-   */
-  isEqualBufferType : function(i_type_value){},
-  /**
-   * getBufferがオブジェクトを返せるかの真偽値です。
-   * @return
-   */
-  hasBuffer : function(){},
-  /**
-   * i_ref_bufをラップします。できる限り整合性チェックを行います。
-   * バッファの再ラッピングが可能な関数のみ、この関数を実装してください。
-   * @param i_ref_buf
-   */
-  wrapBuffer : function(i_ref_buf){}
-})
-
-NyARRaster_BasicClass = ASKlass('NyARRaster_BasicClass', INyARRaster,
-{
-  _size : null,
-  _buffer_type : 0,
-  /*
-   * ,NyARRaster_BasicClass : function(int i_width,int i_height,int i_buffer_type)
-   */
-  NyARRaster_BasicClass : function()
-  {
-    switch(arguments.length) {
-    case 1:
-      if (arguments[0] == NyAS3Const_Inherited) {
-        //blank
-      }
-      break;
-    case 3:
-      this.overload_NyARRaster_BasicClass(toInt(arguments[0]),toInt(arguments[1]),toInt(arguments[2]));
-      break;
-    default:
-      throw new NyARException();
-    }
-  }
-  ,overload_NyARRaster_BasicClass : function(i_width ,i_height,i_buffer_type)
-  {
-    this._size = new NyARIntSize(i_width, i_height);
-    this._buffer_type=i_buffer_type;
-  }
-  ,getWidth : function()
-  {
-    return this._size.w;
-  }
-  ,getHeight : function()
-  {
-    return this._size.h;
-  }
-  ,getSize : function()
-  {
-    return this._size;
-  }
-  ,getBufferType : function()
-  {
-    return this._buffer_type;
-  }
-  ,isEqualBufferType : function(i_type_value)
-  {
-    return this._buffer_type==i_type_value;
-  }
-  ,getBuffer : function()
-  {
-    throw new NyARException();
-  }
-  ,hasBuffer : function()
-  {
-    throw new NyARException();
-  }
-  ,wrapBuffer : function(i_ref_buf)
-  {
-    throw new NyARException();
-  }
-})
-
-NyARBinRaster = ASKlass('NyARBinRaster', NyARRaster_BasicClass,
-{
-  _buf : null,
-  /**
-   * バッファオブジェクトがアタッチされていればtrue
-   */
-  _is_attached_buffer : null,
-  /**
-   *
-   */
-  NyARBinRaster : function()
-  {
-    NyARRaster_BasicClass.initialize.call(this, NyAS3Const_Inherited);
-    switch(arguments.length) {
-    case 1:
-      if (arguments[0] == NyAS3Const_Inherited) {
-        //blank
-      }
-      break;
-    case 2:
-      //(int,int)
-      this.override_NyARBinRaster2(toInt(arguments[0]), toInt(arguments[1]));
-      break;
-    case 3:
-      //(int,int,bool)
-      this.override_NyARBinRaster3(toInt(arguments[0]), toInt(arguments[1]),Boolean(arguments[2]));
-      break;
-    case 4:
-      //(int,int,int,bool)
-      this.override_NyARBinRaster4(toInt(arguments[0]), toInt(arguments[1]),toInt(arguments[2]),Boolean(arguments[3]));
-      break;
-    default:
-      throw new NyARException();
-    }
-  }
-  /**
-   *
-   * @param i_width
-   * @param i_height
-   * @param i_raster_type
-   * NyARBufferTypeに定義された定数値を指定してください。
-   * @param i_is_alloc
-   * @throws NyARException
-   */
-  ,override_NyARBinRaster4 : function(i_width, i_height, i_raster_type, i_is_alloc)
-  {
-    NyARRaster_BasicClass.overload_NyARRaster_BasicClass.call(this,i_width,i_height,i_raster_type);
-    if(!this.initInstance(this._size,i_raster_type,i_is_alloc)){
-      throw new NyARException();
-    }
-  }
-  ,override_NyARBinRaster3 : function(i_width, i_height, i_is_alloc)
-  {
-    NyARRaster_BasicClass.overload_NyARRaster_BasicClass.call(this,i_width,i_height,NyARBufferType.INT1D_BIN_8);
-    if(!this.initInstance(this._size,NyARBufferType.INT1D_BIN_8,i_is_alloc)){
-      throw new NyARException();
-    }
-  }
-  ,override_NyARBinRaster2 : function(i_width, i_height)
-  {
-    NyARRaster_BasicClass.overload_NyARRaster_BasicClass.call(this,i_width,i_height,NyARBufferType.INT1D_BIN_8);
-    if(!this.initInstance(this._size,NyARBufferType.INT1D_BIN_8,true)){
-      throw new NyARException();
-    }
-  }
-  ,initInstance : function(i_size,i_buf_type,i_is_alloc)
-  {
-    switch(i_buf_type)
-    {
-      case NyARBufferType.INT1D_BIN_8:
-        this._buf = i_is_alloc?new IntVector(i_size.w*i_size.h):null;
-        break;
-      default:
-        return false;
-    }
-    this._is_attached_buffer=i_is_alloc;
-    return true;
-  }
-  ,getBuffer : function()
-  {
-    return this._buf;
-  }
-  /**
-   * インスタンスがバッファを所有するかを返します。
-   * コンストラクタでi_is_allocをfalseにしてラスタを作成した場合、
-   * バッファにアクセスするまえに、バッファの有無をこの関数でチェックしてください。
-   * @return
-   */
-  ,hasBuffer : function()
-  {
-    return this._buf!=null;
-  }
-  ,wrapBuffer : function(i_ref_buf)
-  {
-    NyAS3Utils.assert(!this._is_attached_buffer);//バッファがアタッチされていたら機能しない。
-    this._buf=i_ref_buf;
-  }
-})
-
-
-
-
-
-NyARGrayscaleRaster = ASKlass('NyARGrayscaleRaster', NyARRaster_BasicClass,
-{
-  _buf : null,
-  /**
-   * バッファオブジェクトがアタッチされていればtrue
-   */
-  _is_attached_buffer : null,
-  NyARGrayscaleRaster : function()
-  {
-    NyARRaster_BasicClass.initialize.call(this, NyAS3Const_Inherited);
-    switch(arguments.length) {
-    case 1:
-      if (arguments[0] == NyAS3Const_Inherited) {
-        //blank
-      }
-      break;
-    case 2:
-      //(int,int)
-      this.overload_NyARGrayscaleRaster2(toInt(arguments[0]), toInt(arguments[1]));
-      break;
-    case 3:
-      //(int,int,boolean)
-      this.overload_NyARGrayscaleRaster3(toInt(arguments[0]), toInt(arguments[1]),Boolean(arguments[2]));
-      break;
-    case 4:
-      //(int,int,int,boolean)
-      this.overload_NyARGrayscaleRaster4(toInt(arguments[0]), toInt(arguments[1]),toInt(arguments[2]),Boolean(arguments[3]));
-      break;
-    default:
-      throw new NyARException();
-    }
-  }
-  ,overload_NyARGrayscaleRaster2 : function(i_width,i_height)
-  {
-    NyARRaster_BasicClass.overload_NyARRaster_BasicClass.call(this,i_width,i_height,NyARBufferType.INT1D_GRAY_8);
-    if(!this.initInstance(this._size,NyARBufferType.INT1D_GRAY_8,true)){
-      throw new NyARException();
-    }
-  }
-  ,overload_NyARGrayscaleRaster3 : function(i_width,i_height,i_is_alloc)
-  {
-    NyARRaster_BasicClass.overload_NyARRaster_BasicClass.call(this,i_width,i_height,NyARBufferType.INT1D_GRAY_8);
-    if(!this.initInstance(this._size,NyARBufferType.INT1D_GRAY_8,i_is_alloc)){
-      throw new NyARException();
-    }
-  }
-  /**
-   * @param i_width
-   * @param i_height
-   * @param i_raster_type
-   * NyARBufferTypeに定義された定数値を指定してください。
-   * @param i_is_alloc
-   * @throws NyARException
-   */
-  ,overload_NyARGrayscaleRaster4 : function(i_width, i_height, i_raster_type, i_is_alloc)
-  {
-    NyARRaster_BasicClass.overload_NyARRaster_BasicClass.call(this,i_width,i_height,i_raster_type);
-    if(!this.initInstance(this._size,i_raster_type,i_is_alloc)){
-      throw new NyARException();
-    }
-  }
-  ,initInstance : function(i_size,i_buf_type,i_is_alloc)
-  {
-    switch(i_buf_type)
-    {
-      case NyARBufferType.INT1D_GRAY_8:
-        this._buf =i_is_alloc?new IntVector(i_size.w*i_size.h):null;
-        break;
-      default:
-        return false;
-    }
-    this._is_attached_buffer=i_is_alloc;
-    return true;
-  }
-  ,getBuffer : function()
-  {
-    return this._buf;
-  }
-  /**
-   * インスタンスがバッファを所有するかを返します。
-   * コンストラクタでi_is_allocをfalseにしてラスタを作成した場合、
-   * バッファにアクセスするまえに、バッファの有無をこの関数でチェックしてください。
-   * @return
-   */
-  ,hasBuffer : function()
-  {
-    return this._buf!=null;
-  }
-  ,wrapBuffer : function(i_ref_buf)
-  {
-    NyAS3Utils.assert(!this._is_attached_buffer);//バッファがアタッチされていたら機能しない。
-    this._buf=i_ref_buf;
-  }
-})
-
-
-
-
-/**このクラスは、単機能のNyARRasterです。
- *
- */
-NyARRaster = ASKlass('NyARRaster', NyARRaster_BasicClass,
-{
-  _buf : null,
-  _buf_type : 0,
-  /**
-   * バッファオブジェクトがアタッチされていればtrue
-   */
-  _is_attached_buffer : null,
-  NyARRaster : function()
-  {
-    NyARRaster_BasicClass.initialize.call(this, NyAS3Const_Inherited);
-    switch(arguments.length) {
-    case 1:
-      if (arguments[0] == NyAS3Const_Inherited) {
-        //blank
-      }
-      break;
-    case 3:
-      this.overload_NyARRaster3(toInt(arguments[0]), toInt(arguments[1]),toInt(arguments[2]));
-      break;
-    case 4:
-      this.overload_NyARRaster4(toInt(arguments[0]), toInt(arguments[1]),toInt(arguments[2]),Boolean(arguments[3]));
-      break;
-    default:
-      throw new NyARException();
-    }
-  }
-  /**
-   * 指定したバッファタイプのラスタを作成します。
-   * @param i_width
-   * @param i_height
-   * @param i_buffer_type
-   * NyARBufferTypeに定義された定数値を指定してください。
-   * @param i_is_alloc
-   * @throws NyARException
-   */
-  ,overload_NyARRaster4 : function(i_width, i_height, i_buffer_type, i_is_alloc)
-  {
-    NyARRaster_BasicClass.overload_NyARRaster_BasicClass.call(this,i_width,i_height,i_buffer_type);
-    if(!this.initInstance(this._size,i_buffer_type,i_is_alloc)){
-      throw new NyARException();
-    }
-    return;
-  }
-  ,overload_NyARRaster3 : function(i_width, i_height, i_buffer_type)
-  {
-    NyARRaster_BasicClass.overload_NyARRaster_BasicClass.call(this,i_width,i_height,i_buffer_type);
-    if(!this.initInstance(this._size,i_buffer_type,true)){
-      throw new NyARException();
-    }
-    return;
-  }
-  ,initInstance : function(i_size,i_buf_type,i_is_alloc)
-  {
-    switch(i_buf_type)
-    {
-      case NyARBufferType.INT1D_X8R8G8B8_32:
-        this._buf=i_is_alloc?new IntVector(i_size.w*i_size.h):null;
-        break;
-      default:
-        return false;
-    }
-    this._is_attached_buffer=i_is_alloc;
-    return true;
-  }
-  ,getBuffer : function()
-  {
-    return this._buf;
-  }
-  /**
-   * インスタンスがバッファを所有するかを返します。
-   * コンストラクタでi_is_allocをfalseにしてラスタを作成した場合、
-   * バッファにアクセスするまえに、バッファの有無をこの関数でチェックしてください。
-   * @return
-   */
-  ,hasBuffer : function()
-  {
-    return this._buf!=null;
-  }
-  ,wrapBuffer : function(i_ref_buf)
-  {
-    NyAS3Utils.assert(!this._is_attached_buffer);//バッファがアタッチされていたら機能しない。
-    this._buf=i_ref_buf;
-  }
-})
-
-
-/**
- * 8bitRGBを表現できるラスタ
- *
- */
-INyARRgbRaster = ASKlass('INyARRgbRaster', INyARRaster, {
-  getRgbPixelReader : function(){}
-})
-/**
- * NyARRasterインタフェイスの基本関数/メンバを実装したクラス
- *
- *
- */
-NyARRgbRaster_BasicClass = ASKlass('NyARRgbRaster_BasicClass', INyARRgbRaster,
-{
-  _size : null,
-  _buffer_type : 0,
-  NyARRgbRaster_BasicClass : function()
-  {
-    switch(arguments.length) {
-    case 1:
-      if (arguments[0] == NyAS3Const_Inherited) {
-        //blank
-      }
-      break;
-    case 3:
-      //(int,int,int)
-      this.overload_NyARRgbRaster_BasicClass(toInt(arguments[0]),toInt(arguments[1]),toInt(arguments[2]));
-      break;
-    default:
-      throw new NyARException();
-    }
-  }
-  ,overload_NyARRgbRaster_BasicClass : function(i_width,i_height,i_buffer_type)
-  {
-    this._size= new NyARIntSize(i_width,i_height);
-    this._buffer_type=i_buffer_type;
-  }
-  ,getWidth : function()
-  {
-    return this._size.w;
-  }
-  ,getHeight : function()
-  {
-    return this._size.h;
-  }
-  ,getSize : function()
-  {
-    return this._size;
-  }
-  ,getBufferType : function()
-  {
-    return this._buffer_type;
-  }
-  ,isEqualBufferType : function(i_type_value)
-  {
-    return this._buffer_type==i_type_value;
-  }
-  ,getRgbPixelReader : function()
-  {
-    throw new NyARException();
-  }
-  ,getBuffer : function()
-  {
-    throw new NyARException();
-  }
-  ,hasBuffer : function()
-  {
-    throw new NyARException();
-  }
-  ,wrapBuffer : function(i_ref_buf)
-  {
-    throw new NyARException();
-  }
-})
-
-NyARRgbRaster = ASKlass('NyARRgbRaster', NyARRgbRaster_BasicClass,
-{
-  _buf : null,
-  _reader : null,
-  /**
-   * バッファオブジェクトがアタッチされていればtrue
-   */
-  _is_attached_buffer : null,
-  NyARRgbRaster : function()
-  {
-    NyARRgbRaster_BasicClass.initialize.call(this, NyAS3Const_Inherited);
-    switch(arguments.length) {
-    case 1:
-      if (arguments[0] == NyAS3Const_Inherited) {
-        //blank
-      }
-      break;
-    case 3:
-      this.overload_NyARRgbRaster3(toInt(arguments[0]), toInt(arguments[1]),toInt(arguments[2]));
-      break;
-    case 4:
-      this.overload_NyARRgbRaster4(toInt(arguments[0]), toInt(arguments[1]),toInt(arguments[2]),Boolean(arguments[3]));
-      break;
-    default:
-      throw new NyARException();
-    }
-  }
-  /**
-   *
-   * @param i_width
-   * @param i_height
-   * @param i_raster_type
-   * NyARBufferTypeに定義された定数値を指定してください。
-   * @param i_is_alloc
-   * @throws NyARException
-   */
-  ,overload_NyARRgbRaster4 : function(i_width,i_height,i_raster_type,i_is_alloc)
-  {
-    NyARRgbRaster_BasicClass.overload_NyARRgbRaster_BasicClass.call(this,i_width,i_height,i_raster_type);
-    if(!this.initInstance(this._size,i_raster_type,i_is_alloc)){
-      throw new NyARException();
-    }
-  }
-  /**
-   *
-   * @param i_width
-   * @param i_height
-   * @param i_raster_type
-   * NyARBufferTypeに定義された定数値を指定してください。
-   * @throws NyARException
-   */
-  ,overload_NyARRgbRaster3 : function(i_width, i_height, i_raster_type)
-  {
-    NyARRgbRaster_BasicClass.overload_NyARRgbRaster_BasicClass.call(this,i_width,i_height,i_raster_type);
-    if(!this.initInstance(this._size,i_raster_type,true)){
-      throw new NyARException();
-    }
-  }
-  ,initInstance : function(i_size,i_raster_type,i_is_alloc)
-  {
-    switch(i_raster_type)
-    {
-      case NyARBufferType.INT1D_X8R8G8B8_32:
-        this._buf=i_is_alloc?new IntVector(i_size.w*i_size.h):null;
-        this._reader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._buf||new IntVector(1),i_size);
-        break;
-      case NyARBufferType.BYTE1D_B8G8R8X8_32:
-      case NyARBufferType.BYTE1D_R8G8B8_24:
-      default:
-        return false;
-    }
-    this._is_attached_buffer=i_is_alloc;
-    return true;
-  }
-  ,getRgbPixelReader : function()
-  {
-    return this._reader;
-  }
-  ,getBuffer : function()
-  {
-    return this._buf;
-  }
-  ,hasBuffer : function()
-  {
-    return this._buf!=null;
-  }
-  ,wrapBuffer : function(i_ref_buf)
-  {
-    NyAS3Utils.assert(!this._is_attached_buffer);//バッファがアタッチされていたら機能しない。
-    this._buf=i_ref_buf;
-    //ピクセルリーダーの参照バッファを切り替える。
-    this._reader.switchBuffer(i_ref_buf);
-  }
-})
-
-
-
-NyARRgbRaster_Canvas2D = ASKlass("NyARRgbRaster_Canvas2D", NyARRgbRaster_BasicClass,
-{
-  _canvas : null,
-  _rgb_reader: null,
-
-  NyARRgbRaster_Canvas2D : function(canvas) {
-    NyARRgbRaster_BasicClass.initialize.call(this, canvas.width, canvas.height, NyARBufferType.OBJECT_JS_Canvas);
-    this._canvas = canvas;
-    this._rgb_reader = new NyARRgbPixelReader_Canvas2D(this._canvas);
-  },
-  getRgbPixelReader : function()
-  {
-    return this._rgb_reader;
-  },
-  getBuffer:function()
-  {
-    return this._canvas;
-  },
-  hasBuffer:function()
-  {
-    return this._bitmapData != null;
-  }
-})
-
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * PROJECT: FLARToolKit
- * --------------------------------------------------------------------------------
- * This work is based on the NyARToolKit developed by
- *   R.Iizuka (nyatla)
- * http://nyatla.jp/nyatoolkit/
- *
- * The FLARToolKit is ActionScript 3.0 version ARToolkit class library.
- * Copyright (C)2008 Saqoosha
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  http://www.libspark.org/wiki/saqoosha/FLARToolKit
- *  <saq(at)saqoosha.net>
- *
- */
-
-
-FLARCanvas = function(w,h) {
-  var c = document.createElement('canvas');
-  c.width = w;
-  c.height = h;
-  return c;
-}
-
-
-
-FLARBinRaster = ASKlass('FLARBinRaster', NyARBinRaster,
-{
-  FLARBinRaster : function(i_width,i_height)
-  {
-    NyARBinRaster.initialize.call(this,i_width,i_height,NyARBufferType.OBJECT_AS3_BitmapData,true);
-    this._gray_reader = new FLARGrayPixelReader_BitmapData(this._buf);
-  }
-  ,initInstance : function(i_size,i_buf_type,i_is_alloc)
-  {
-    this._buf = i_is_alloc?new BitmapData(i_size.w,i_size.h,0x00):null;
-    return true;
-  }
-  ,getGrayPixelReader : function() {
-    return this._gray_reader;
-  }
-})
-
-
-FLARRgbRaster_BitmapData = ASKlass('FLARRgbRaster_BitmapData', NyARRgbRaster_BasicClass,
-{
-  _bitmapData : null
-  ,_rgb_reader : null
-  /**
-   *
-   * @deprecated 次バージョンで次のように変更されます。 FLARRgbRaster_BitmapData(i_width,i_height)
-   */
-  ,FLARRgbRaster_BitmapData : function(bitmapData) {
-    NyARRgbRaster_BasicClass.initialize.call(this,bitmapData.width, bitmapData.height,NyARBufferType.OBJECT_AS3_BitmapData);
-    this._bitmapData = bitmapData;
-    this._rgb_reader = new FLARRgbPixelReader_BitmapData(this._bitmapData);
-  }
-  ,getRgbPixelReader : function()
-  {
-    return this._rgb_reader;
-  }
-  ,getBuffer : function()
-  {
-    return this._bitmapData;
-  }
-  ,hasBuffer : function()
-  {
-    return this._bitmapData != null;
-  }
-})
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * JSARToolkit
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- *   Hirokazu Kato
- *   Mark Billinghurst
- *   HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * And the NyARToolkitAS3 ARToolKit class library.
- *   Copyright (C)2010 Ryo Iizuka
- *
- * JSARToolkit is a JavaScript port of NyARToolkitAS3.
- *   Copyright (C)2010 Ilmari Heikkinen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  ilmari.heikkinen@gmail.com
- *
- */
-
-
-NyARMatchPattDeviationBlackWhiteData = ASKlass('NyARMatchPattDeviationBlackWhiteData',
-{
-  _data : null,
-  _pow : 0,
-  //
-  _number_of_pixels : 0,
-  refData : function()
-  {
-    return this._data;
-  }
-  ,getPow : function()
-  {
-    return this._pow;
-  }
-  ,NyARMatchPattDeviationBlackWhiteData : function(i_width,i_height)
-  {
-    this._number_of_pixels=i_height*i_width;
-    this._data=new IntVector(this._number_of_pixels);
-    return;
-  }
-  /**
-   * XRGB[width*height]の配列から、パターンデータを構築。
-   * @param i_buffer
-   */
-  ,setRaster : function(i_raster)
-  {
-    //i_buffer[XRGB]→差分[BW]変換
-    var i;
-    var ave;//<PV/>
-    var rgb;//<PV/>
-    var linput=this._data;//<PV/>
-    var buf=(i_raster.getBuffer());
-    // input配列のサイズとwhも更新// input=new int[height][width][3];
-    var number_of_pixels=this._number_of_pixels;
-    //<平均値計算(FORの1/8展開)/>
-    ave = 0;
-    for(i=number_of_pixels-1;i>=0;i--){
-      rgb = buf[i];
-      ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);
-    }
-    ave=(number_of_pixels*255*3-ave)/(3*number_of_pixels);
-    //
-    var sum = 0,w_sum;
-    //<差分値計算/>
-    for (i = number_of_pixels-1; i >= 0;i--) {
-      rgb = buf[i];
-      w_sum =((255*3-(rgb & 0xff)-((rgb >> 8) & 0xff)-((rgb >> 16) & 0xff))/3)-ave;
-      linput[i] = w_sum;
-      sum += w_sum * w_sum;
-    }
-    var p=Math.sqrt(sum);
-    this._pow=p!=0.0?p:0.0000001;
-    return;
-  }
-})
-NyARMatchPattDeviationColorData = ASKlass('NyARMatchPattDeviationColorData',
-{
-  _data : null,
-  _pow : 0,
-  //
-  _number_of_pixels : 0,
-  _optimize_for_mod : 0,
-  refData : function()
-  {
-    return this._data;
-  }
-  ,getPow : function()
-  {
-    return this._pow;
-  }
-  ,NyARMatchPattDeviationColorData : function(i_width,i_height)
-  {
-    this._number_of_pixels=i_height*i_width;
-    this._data=new IntVector(this._number_of_pixels*3);
-    this._optimize_for_mod=this._number_of_pixels-(this._number_of_pixels%8);
-    return;
-  }
-  /**
-   * NyARRasterからパターンデータをセットします。
-   * この関数は、データを元に所有するデータ領域を更新します。
-   * @param i_buffer
-   */
-  ,setRaster : function(i_raster)
-  {
-    //画素フォーマット、サイズ制限
-    NyAS3Utils.assert(i_raster.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));
-    NyAS3Utils.assert(i_raster.getSize().isEqualSize_NyARIntSize(i_raster.getSize()));
-    var buf=(i_raster.getBuffer());
-    //i_buffer[XRGB]→差分[R,G,B]変換
-    var i;
-    var ave;//<PV/>
-    var rgb;//<PV/>
-    var linput=this._data;//<PV/>
-    // input配列のサイズとwhも更新// input=new int[height][width][3];
-    var number_of_pixels=this._number_of_pixels;
-    var for_mod=this._optimize_for_mod;
-    //<平均値計算(FORの1/8展開)>
-    ave = 0;
-    for(i=number_of_pixels-1;i>=for_mod;i--){
-      rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);
-    }
-    for (;i>=0;) {
-      rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;
-      rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;
-      rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;
-      rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;
-      rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;
-      rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;
-      rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;
-      rgb = buf[i];ave += ((rgb >> 16) & 0xff) + ((rgb >> 8) & 0xff) + (rgb & 0xff);i--;
-    }
-    //<平均値計算(FORの1/8展開)/>
-    ave=number_of_pixels*255*3-ave;
-    ave =255-(ave/ (number_of_pixels * 3));//(255-R)-ave を分解するための事前計算
-    var sum = 0,w_sum;
-    var input_ptr=number_of_pixels*3-1;
-    //<差分値計算(FORの1/8展開)>
-    for (i = number_of_pixels-1; i >= for_mod;i--) {
-      rgb = buf[i];
-      w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B
-      w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G
-      w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R
-    }
-    for (; i >=0;) {
-      rgb = buf[i];i--;
-      w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B
-      w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G
-      w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R
-      rgb = buf[i];i--;
-      w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B
-      w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G
-      w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R
-      rgb = buf[i];i--;
-      w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B
-      w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G
-      w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R
-      rgb = buf[i];i--;
-      w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B
-      w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G
-      w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R
-      rgb = buf[i];i--;
-      w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B
-      w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G
-      w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R
-      rgb = buf[i];i--;
-      w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B
-      w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G
-      w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R
-      rgb = buf[i];i--;
-      w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B
-      w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G
-      w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R
-      rgb = buf[i];i--;
-      w_sum = (ave - (rgb & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//B
-      w_sum = (ave - ((rgb >> 8) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//G
-      w_sum = (ave - ((rgb >> 16) & 0xff)) ;linput[input_ptr--] = w_sum;sum += w_sum * w_sum;//R
-    }
-    //<差分値計算(FORの1/8展開)/>
-    var p=Math.sqrt(sum);
-    this._pow=p!=0.0?p:0.0000001;
-    return;
-  }
-})
-NyARMatchPattResult = ASKlass('NyARMatchPattResult',
-{
-  DIRECTION_UNKNOWN : -1,
-  confidence : 0,
-  direction : 0
-})
-
-
-
-/**
- * ARToolKitのマーカーコードを1個保持します。
- *
- */
-NyARCode = ASKlass('NyARCode',
-{
-  _color_pat : new Array(4),
-  _bw_pat : new Array(4),
-  _width : 0,
-  _height : 0,
-  NyARCode : function(i_width, i_height)
-  {
-    this._width = i_width;
-    this._height = i_height;
-    //空のラスタを4個作成
-    for(var i=0;i<4;i++){
-      this._color_pat[i]=new NyARMatchPattDeviationColorData(i_width,i_height);
-      this._bw_pat[i]=new NyARMatchPattDeviationBlackWhiteData(i_width,i_height);
-    }
-    return;
-  }
-  ,getColorData : function(i_index)
-  {
-    return this._color_pat[i_index];
-  }
-  ,getBlackWhiteData : function(i_index)
-  {
-    return this._bw_pat[i_index];
-  }
-  ,getWidth : function()
-  {
-    return this._width;
-  }
-  ,getHeight : function()
-  {
-    return this._height;
-  }
-  ,loadARPattFromFile : function(i_stream)
-  {
-    NyARCodeFileReader.loadFromARToolKitFormFile(i_stream,this);
-    return;
-  }
-  ,setRaster : function(i_raster)
-  {
-    NyAS3Utils.assert(i_raster.length!=4);
-    //ラスタにパターンをロードする。
-    for(var i=0;i<4;i++){
-      this._color_pat[i].setRaster(i_raster[i]);
-    }
-    return;
-  }
-})
-
-
-
-
-
-
-NyARCodeFileReader = ASKlass('NyARCodeFileReader',
-{
-
-  /**
-  * ARコードファイルからデータを読み込んでo_codeに格納します。
-  * @param i_stream
-  * @param o_code
-  * @throws NyARException
-  */
-  loadFromARToolKitFormFile : function(i_stream,o_code)
-  {
-    var width=o_code.getWidth();
-    var height=o_code.getHeight();
-    var tmp_raster=new NyARRaster(width,height,NyARBufferType.INT1D_X8R8G8B8_32);
-    //4個の要素をラスタにセットする。
-    var token = i_stream.match(/\d+/g);
-    var buf=(tmp_raster.getBuffer());
-    //GBRAで一度読みだす。
-    for (var h = 0; h < 4; h++){
-      this.readBlock(token,width,height,buf);
-      //ARCodeにセット(カラー)
-      o_code.getColorData(h).setRaster(tmp_raster);
-      o_code.getBlackWhiteData(h).setRaster(tmp_raster);
-    }
-    tmp_raster=null;//ポイ
-    return;
-  }
-  /**
-  * 1ブロック分のXRGBデータをi_stからo_bufへ読みだします。
-  * @param i_st
-  * @param o_buf
-  */
-  ,readBlock : function(i_st, i_width, i_height, o_buf)
-  {
-    var pixels = i_width * i_height;
-    var i3;
-    for (i3 = 0; i3 < 3; i3++) {
-      for (var i2 = 0; i2 < pixels; i2++){
-        // 数値のみ読み出す
-        var val = parseInt(i_st.shift());
-        if(isNaN(val)){
-          throw new NyARException("syntax error in pattern file.");
-        }
-        o_buf[i2]=(o_buf[i2]<<8)|((0x000000ff&toInt(val)));
-      }
-    }
-    //GBR→RGB
-    for(i3=0;i3<pixels;i3++){
-      o_buf[i3]=((o_buf[i3]<<16)&0xff0000)|(o_buf[i3]&0x00ff00)|((o_buf[i3]>>16)&0x0000ff);
-    }
-    return;
-  }
-})
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * JSARToolkit
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- *   Hirokazu Kato
- *   Mark Billinghurst
- *   HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * And the NyARToolkitAS3 ARToolKit class library.
- *   Copyright (C)2010 Ryo Iizuka
- *
- * JSARToolkit is a JavaScript port of NyARToolkitAS3.
- *   Copyright (C)2010 Ilmari Heikkinen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  ilmari.heikkinen@gmail.com
- *
- */
-
-/**
- * ARColorPattのマッチング計算をするインタフェイスです。 基準Patに対して、計算済みのARCodeデータとの間で比較演算をします。
- * pattern_match関数を分解した３種類のパターン検出クラスを定義します。
- *
- */
-INyARMatchPatt = ASKlass('INyARMatchPatt',
-{
-  setARCode : function(i_code){}
-})
-NyARMatchPatt_Color_WITHOUT_PCA = ASKlass('NyARMatchPatt_Color_WITHOUT_PCA', INyARMatchPatt,
-{
-  _code_patt : null,
-  _optimize_for_mod : 0,
-  _rgbpixels : 0,
-  NyARMatchPatt_Color_WITHOUT_PCA : function()
-  {
-    switch(arguments.length){
-    case 1:
-      {  //,NyARMatchPatt_Color_WITHOUT_PCA : function(i_code_ref)
-        var i_code_ref=arguments[0];
-        var w=i_code_ref.getWidth();
-        var h=i_code_ref.getHeight();
-        //最適化定数の計算
-        this._rgbpixels=w*h*3;
-        this._optimize_for_mod=this._rgbpixels-(this._rgbpixels%16);
-        this.setARCode(i_code_ref);
-        return;
-      }
-      break;
-    case 2:
-      {  //,NyARMatchPatt_Color_WITHOUT_PCA : function(i_width,i_height)
-        var i_width = toInt(arguments[0]), i_height = toInt(arguments[1]);
-        //最適化定数の計算
-        this._rgbpixels=i_height*i_width*3;
-        this._optimize_for_mod=this._rgbpixels-(this._rgbpixels%16);
-        return;
-      }
-      break;
-    default:
-      break;
-    }
-    throw new NyARException();
-  }
-  /**
-   * 比較対象のARCodeをセットします。
-   * @throws NyARException
-   */
-  ,setARCode : function(i_code_ref)
-  {
-    this._code_patt=i_code_ref;
-    return;
-  }
-  /**
-   * 現在セットされているARコードとi_pattを比較します。
-   */
-  ,evaluate : function(i_patt,o_result)
-  {
-    NyAS3Utils.assert(this._code_patt!=null);
-    //
-    var linput = i_patt.refData();
-    var sum;
-    var max = Number.MIN_VALUE;
-    var res = NyARMatchPattResult.DIRECTION_UNKNOWN;
-    var for_mod=this._optimize_for_mod;
-    for (var j = 0; j < 4; j++) {
-      //合計値初期化
-      sum=0;
-      var code_patt=this._code_patt.getColorData(j);
-      var pat_j = code_patt.refData();
-      //<全画素について、比較(FORの1/16展開)>
-      var i;
-      for(i=this._rgbpixels-1;i>=for_mod;i--){
-        sum += linput[i] * pat_j[i];
-      }
-      for (;i>=0;) {
-        sum += linput[i] * pat_j[i];i--;
-        sum += linput[i] * pat_j[i];i--;
-        sum += linput[i] * pat_j[i];i--;
-        sum += linput[i] * pat_j[i];i--;
-        sum += linput[i] * pat_j[i];i--;
-        sum += linput[i] * pat_j[i];i--;
-        sum += linput[i] * pat_j[i];i--;
-        sum += linput[i] * pat_j[i];i--;
-        sum += linput[i] * pat_j[i];i--;
-        sum += linput[i] * pat_j[i];i--;
-        sum += linput[i] * pat_j[i];i--;
-        sum += linput[i] * pat_j[i];i--;
-        sum += linput[i] * pat_j[i];i--;
-        sum += linput[i] * pat_j[i];i--;
-        sum += linput[i] * pat_j[i];i--;
-        sum += linput[i] * pat_j[i];i--;
-      }
-      //<全画素について、比較(FORの1/16展開)/>
-      var sum2 = sum / code_patt.getPow();// sum2 = sum / patpow[k][j]/ datapow;
-      if (sum2 > max) {
-        max = sum2;
-        res = j;
-      }
-    }
-    o_result.direction = res;
-    o_result.confidence= max/i_patt.getPow();
-    return true;
-  }
-})
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * JSARToolkit
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- *   Hirokazu Kato
- *   Mark Billinghurst
- *   HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * And the NyARToolkitAS3 ARToolKit class library.
- *   Copyright (C)2010 Ryo Iizuka
- *
- * JSARToolkit is a JavaScript port of NyARToolkitAS3.
- *   Copyright (C)2010 Ilmari Heikkinen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  ilmari.heikkinen@gmail.com
- *
- */
-NyARRasterAnalyzer_Histogram = ASKlass('NyARRasterAnalyzer_Histogram',
-{
-  _histImpl : null,
-  /**
-   * ヒストグラム解析の縦方向スキップ数。継承クラスはこのライン数づつ
-   * スキップしながらヒストグラム計算を行うこと。
-   */
-  _vertical_skip : 0,
-  NyARRasterAnalyzer_Histogram : function(i_raster_format, i_vertical_interval)
-  {
-    if(!this.initInstance(i_raster_format,i_vertical_interval)){
-      throw new NyARException();
-    }
-  }
-  ,initInstance : function(i_raster_format,i_vertical_interval)
-  {
-    switch (i_raster_format) {
-    case NyARBufferType.INT1D_GRAY_8:
-      this._histImpl = new NyARRasterThresholdAnalyzer_Histogram_INT1D_GRAY_8();
-      break;
-    case NyARBufferType.INT1D_X8R8G8B8_32:
-      this._histImpl = new NyARRasterThresholdAnalyzer_Histogram_INT1D_X8R8G8B8_32();
-      break;
-    default:
-      return false;
-    }
-    //初期化
-    this._vertical_skip=i_vertical_interval;
-    return true;
-  }
-  ,setVerticalInterval : function(i_step)
-  {
-    this._vertical_skip=i_step;
-    return;
-  }
-  /**
-   * o_histgramにヒストグラムを出力します。
-   * @param i_input
-   * @param o_histgram
-   * @return
-   * @throws NyARException
-   */
-  ,analyzeRaster : function(i_input,o_histgram)
-  {
-    var size=i_input.getSize();
-    //最大画像サイズの制限
-    NyAS3Utils.assert(size.w*size.h<0x40000000);
-    NyAS3Utils.assert(o_histgram.length == 256);//現在は固定
-    var  h=o_histgram.data;
-    //ヒストグラム初期化
-    for (var i = o_histgram.length-1; i >=0; i--){
-      h[i] = 0;
-    }
-    o_histgram.total_of_data=size.w*size.h/this._vertical_skip;
-    return this._histImpl.createHistogram(i_input, size,h,this._vertical_skip);
-  }
-})
-ICreateHistogramImpl = ASKlass('ICreateHistogramImpl',
-{
-  createHistogram : function(i_reader,i_size,o_histgram,i_skip){}
-})
-
-NyARRasterThresholdAnalyzer_Histogram_INT1D_GRAY_8 = ASKlass('NyARRasterThresholdAnalyzer_Histogram_INT1D_GRAY_8', ICreateHistogramImpl,
-{
-  createHistogram : function(i_reader,i_size,o_histgram,i_skip)
-  {
-    NyAS3Utils.assert (i_reader.isEqualBufferType(NyARBufferType.INT1D_GRAY_8));
-    var input=(IntVector)(i_reader.getBuffer());
-    for (var y = i_size.h-1; y >=0 ; y-=i_skip){
-      var pt=y*i_size.w;
-      for (var x = i_size.w-1; x >=0; x--) {
-        o_histgram[input[pt]]++;
-        pt++;
-      }
-    }
-    return i_size.w*i_size.h;
-  }
-})
-NyARRasterThresholdAnalyzer_Histogram_INT1D_X8R8G8B8_32 = ASKlass('NyARRasterThresholdAnalyzer_Histogram_INT1D_X8R8G8B8_32', ICreateHistogramImpl,
-{
-  createHistogram : function(i_reader,i_size,o_histgram,i_skip)
-  {
-    NyAS3Utils.assert (i_reader.isEqualBufferType(NyARBufferType.INT1D_X8R8G8B8_32));
-    var input =(i_reader.getBuffer());
-    for (var y = i_size.h-1; y >=0 ; y-=i_skip){
-      var pt=y*i_size.w;
-      for (var x = i_size.w-1; x >=0; x--) {
-        var p=input[pt];
-        o_histgram[((p& 0xff)+(p& 0xff)+(p& 0xff))/3]++;
-        pt++;
-      }
-    }
-    return i_size.w*i_size.h;
-  }
-})
-INyARRasterThresholdAnalyzer = ASKlass('INyARRasterThresholdAnalyzer',
-{
-  analyzeRaster : function(i_input){}
-})
-NyARRasterThresholdAnalyzer_SlidePTile = ASKlass('NyARRasterThresholdAnalyzer_SlidePTile', INyARRasterThresholdAnalyzer,
-{
-  _raster_analyzer : null,
-  _sptile : null,
-  _histgram : null,
-  NyARRasterThresholdAnalyzer_SlidePTile : function(i_persentage, i_raster_format, i_vertical_interval)
-  {
-    NyAS3Utils.assert (0 <= i_persentage && i_persentage <= 50);
-    //初期化
-    if(!this.initInstance(i_raster_format,i_vertical_interval)){
-      throw new NyARException();
-    }
-    this._sptile=new NyARHistogramAnalyzer_SlidePTile(i_persentage);
-    this._histgram=new NyARHistogram(256);
-  }
-  ,initInstance : function(i_raster_format,i_vertical_interval)
-  {
-    this._raster_analyzer=new NyARRasterAnalyzer_Histogram(i_raster_format,i_vertical_interval);
-    return true;
-  }
-  ,setVerticalInterval : function(i_step)
-  {
-    this._raster_analyzer.setVerticalInterval(i_step);
-    return;
-  }
-  ,analyzeRaster : function(i_input)
-  {
-    this._raster_analyzer.analyzeRaster(i_input, this._histgram);
-    return this._sptile.getThreshold(this._histgram);
-  }
-})
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * PROJECT: FLARToolKit
- * --------------------------------------------------------------------------------
- * This work is based on the NyARToolKit developed by
- *   R.Iizuka (nyatla)
- * http://nyatla.jp/nyatoolkit/
- *
- * The FLARToolKit is ActionScript 3.0 version ARToolkit class library.
- * Copyright (C)2008 Saqoosha
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  http://www.libspark.org/wiki/saqoosha/FLARToolKit
- *  <saq(at)saqoosha.net>
- *
- */
-FLARRasterAnalyzer_Histogram = ASKlass('FLARRasterAnalyzer_Histogram', NyARRasterAnalyzer_Histogram,
-{
-  FLARRasterAnalyzer_Histogram : function(i_vertical_interval)
-  {
-    NyARRasterAnalyzer_Histogram.initialize.call(this,NyARBufferType.OBJECT_AS3_BitmapData,i_vertical_interval);
-  }
-  ,initInstance : function(i_raster_format,i_vertical_interval)
-  {
-    if (i_raster_format != NyARBufferType.OBJECT_AS3_BitmapData) {
-      return false;
-    }else {
-      this._vertical_skip = i_vertical_interval;
-    }
-    return true;
-  }
-  /**
-   * o_histgramにヒストグラムを出力します。
-   * @param i_input
-   * @param o_histgram
-   * @return
-   * @throws NyARException
-   */
-  ,analyzeRaster : function(i_input,o_histgram)
-  {
-    var size=i_input.getSize();
-    //最大画像サイズの制限
-    NyAS3Utils.assert(size.w*size.h<0x40000000);
-    NyAS3Utils.assert(o_histgram.length == 256);//現在は固定
-    var  h=o_histgram.data;
-    //ヒストグラム初期化
-    for (var i = o_histgram.length-1; i >=0; i--){
-      h[i] = 0;
-    }
-    o_histgram.total_of_data=size.w*size.h/this._vertical_skip;
-    return this.createHistgram_AS3_BitmapData(i_input, size,h,this._vertical_skip);
-  }
-  ,createHistgram_AS3_BitmapData : function(i_reader,i_size,o_histgram,i_skip)
-  {
-    //[Todo:]この方法だとパフォーマンスでないから、Bitmapdataの
-    NyAS3Utils.assert (i_reader.isEqualBufferType(NyARBufferType.OBJECT_AS3_BitmapData));
-    var input=(i_reader.getBuffer());
-    for (var y = i_size.h-1; y >=0 ; y-=i_skip){
-      var pt=y*i_size.w;
-      for (var x = i_size.w - 1; x >= 0; x--) {
-        var p=input.getPixel(x,y);
-        o_histgram[toInt((((p>>8)&0xff)+((p>>16)&0xff)+(p&0xff))/3)]++;
-        pt++;
-      }
-    }
-    return i_size.w*i_size.h;
-  }
-})
-
-/*
- * PROJECT: FLARToolKit
- * --------------------------------------------------------------------------------
- * This work is based on the NyARToolKit developed by
- *   R.Iizuka (nyatla)
- * http://nyatla.jp/nyatoolkit/
- *
- * The FLARToolKit is ActionScript 3.0 version ARToolkit class library.
- * Copyright (C)2008 Saqoosha
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  http://www.libspark.org/wiki/saqoosha/FLARToolKit
- *  <saq(at)saqoosha.net>
- *
- */
-FLARRasterThresholdAnalyzer_SlidePTile = ASKlass('FLARRasterThresholdAnalyzer_SlidePTile', NyARRasterThresholdAnalyzer_SlidePTile,
-{
-  FLARRasterThresholdAnalyzer_SlidePTile : function(i_persentage, i_vertical_interval)
-  {
-    NyARRasterThresholdAnalyzer_SlidePTile.initialize.call(this,i_persentage, NyARBufferType.OBJECT_AS3_BitmapData,i_vertical_interval);
-  }
-  ,initInstance : function(i_raster_format,i_vertical_interval)
-  {
-    if (i_raster_format != NyARBufferType.OBJECT_AS3_BitmapData) {
-      return false;
-    }
-    this._raster_analyzer=new FLARRasterAnalyzer_Histogram(i_vertical_interval);
-    return true;
-  }
-})
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * JSARToolkit
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- *   Hirokazu Kato
- *   Mark Billinghurst
- *   HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * And the NyARToolkitAS3 ARToolKit class library.
- *   Copyright (C)2010 Ryo Iizuka
- *
- * JSARToolkit is a JavaScript port of NyARToolkitAS3.
- *   Copyright (C)2010 Ilmari Heikkinen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  ilmari.heikkinen@gmail.com
- *
- */
-NyARContourPickup = ASKlass('NyARContourPickup',
-{
-  //巡回参照できるように、テーブルを二重化
-  //                                           0  1  2  3  4  5  6  7   0  1  2  3  4  5  6
-  _getContour_xdir : new IntVector([0, 1, 1, 1, 0, -1, -1, -1 , 0, 1, 1, 1, 0, -1, -1]),
-  _getContour_ydir : new IntVector([-1,-1, 0, 1, 1, 1, 0,-1 ,-1,-1, 0, 1, 1, 1, 0]),
-  getContour_NyARBinRaster : function(i_raster,i_entry_x,i_entry_y,i_array_size,o_coord_x,o_coord_y)
-  {
-    return this.impl_getContour(i_raster,0,i_entry_x,i_entry_y,i_array_size,o_coord_x,o_coord_y);
-  }
-  /**
-   *
-   * @param i_raster
-   * @param i_th
-   * 画像を２値化するための閾値。暗点&lt;=i_th&lt;明点となります。
-   * @param i_entry_x
-   * 輪郭の追跡開始点を指定します。
-   * @param i_entry_y
-   * @param i_array_size
-   * @param o_coord_x
-   * @param o_coord_y
-   * @return
-   * @throws NyARException
-   */
-  ,getContour_NyARGrayscaleRaster : function(i_raster,i_th,i_entry_x,i_entry_y,i_array_size,o_coord_x,o_coord_y)
-  {
-    return this.impl_getContour(i_raster,i_th,i_entry_x,i_entry_y,i_array_size,o_coord_x,o_coord_y);
-  }
-  /**
-   * ラスタのエントリポイントから辿れる輪郭線を配列に返します。
-   * @param i_raster
-   * @param i_th
-   * 暗点<=th<明点
-   * @param i_entry_x
-   * @param i_entry_y
-   * @param i_array_size
-   * @param o_coord_x
-   * @param o_coord_y
-   * @return
-   * 輪郭線の長さを返します。
-   * @throws NyARException
-   */
-  ,impl_getContour : function(i_raster,i_th,i_entry_x,i_entry_y,i_array_size,o_coord_x,o_coord_y)
-  {
-    var xdir = this._getContour_xdir;// static int xdir[8] = { 0, 1, 1, 1, 0,-1,-1,-1};
-    var ydir = this._getContour_ydir;// static int ydir[8] = {-1,-1, 0, 1, 1, 1, 0,-1};
-    var i_buf=i_raster.getBuffer();
-    var width=i_raster.getWidth();
-    var height=i_raster.getHeight();
-    //クリップ領域の上端に接しているポイントを得る。
-    var coord_num = 1;
-    o_coord_x[0] = i_entry_x;
-    o_coord_y[0] = i_entry_y;
-    var dir = 5;
-    var c = i_entry_x;
-    var r = i_entry_y;
-    for (;;) {
-      dir = (dir + 5) % 8;//dirの正規化
-      //ここは頑張ればもっと最適化できると思うよ。
-      //4隅以外の境界接地の場合に、境界チェックを省略するとかね。
-      if(c>=1 && c<width-1 && r>=1 && r<height-1){
-        for(;;){//gotoのエミュレート用のfor文
-          //境界に接していないとき(暗点判定)
-          if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {
-            break;
-          }
-          dir++;
-          if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {
-            break;
-          }
-          dir++;
-          if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {
-            break;
-          }
-          dir++;
-          if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {
-            break;
-          }
-          dir++;
-          if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {
-            break;
-          }
-          dir++;
-          if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {
-            break;
-          }
-          dir++;
-          if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {
-            break;
-          }
-          dir++;
-          if (i_buf[(r + ydir[dir])*width+(c + xdir[dir])] <= i_th) {
-            break;
-          }
-/*
-          try{
-            BufferedImage b=new BufferedImage(width,height,ColorSpace.TYPE_RGB);
-            NyARRasterImageIO.copy(i_raster, b);
-          ImageIO.write(b,"png",new File("bug.png"));
-          }catch(Exception e){
-          }*/
-          //8方向全て調べたけどラベルが無いよ？
-          throw new NyARException();
-        }
-      }else{
-        //境界に接しているとき
-        var i;
-        for (i = 0; i < 8; i++){
-          var x=c + xdir[dir];
-          var y=r + ydir[dir];
-          //境界チェック
-          if(x>=0 && x<width && y>=0 && y<height){
-            if (i_buf[(y)*width+(x)] <= i_th) {
-              break;
-            }
-          }
-          dir++;//倍長テーブルを参照するので問題なし
-        }
-        if (i == 8) {
-          //8方向全て調べたけどラベルが無いよ？
-          throw new NyARException();// return(-1);
-        }
-      }
-      dir=dir% 8;//dirの正規化
-      // xcoordとycoordをc,rにも保存
-      c = c + xdir[dir];
-      r = r + ydir[dir];
-      o_coord_x[coord_num] = c;
-      o_coord_y[coord_num] = r;
-      // 終了条件判定
-      if (c == i_entry_x && r == i_entry_y){
-        coord_num++;
-        break;
-      }
-      coord_num++;
-      if (coord_num == i_array_size) {
-        //輪郭が末端に達した
-        return coord_num;
-      }
-    }
-    return coord_num;
-  }
-})
-NyARCoord2Linear = ASKlass('NyARCoord2Linear',
-{
-  _xpos : null,
-  _ypos : null,
-  _pca : null,
-  __getSquareLine_evec : new NyARDoubleMatrix22(),
-  __getSquareLine_mean : new FloatVector(2),
-  __getSquareLine_ev : new FloatVector(2),
-  _dist_factor : null,
-  NyARCoord2Linear : function(i_size,i_distfactor_ref)
-  {
-    //歪み計算テーブルを作ると、8*width/height*2の領域を消費します。
-    //領域を取りたくない場合は、i_dist_factor_refの値をそのまま使ってください。
-    this._dist_factor = new NyARObserv2IdealMap(i_distfactor_ref,i_size);
-    // 輪郭バッファ
-    this._pca=new NyARPca2d_MatrixPCA_O2();
-    this._xpos=new FloatVector(i_size.w+i_size.h);//最大辺長はthis._width+this._height
-    this._ypos=new FloatVector(i_size.w+i_size.h);//最大辺長はthis._width+this._height
-    return;
-  }
-  /**
-   * 輪郭点集合からay+bx+c=0の直線式を計算します。
-   * @param i_st
-   * @param i_ed
-   * @param i_xcoord
-   * @param i_ycoord
-   * @param i_cood_num
-   * @param o_line
-   * @return
-   * @throws NyARException
-   */
-  ,coord2Line : function(i_st,i_ed,i_xcoord,i_ycoord,i_cood_num,o_line)
-  {
-    //頂点を取得
-    var n,st,ed;
-    var w1;
-    //探索区間の決定
-    if(i_ed>=i_st){
-      //頂点[i]から頂点[i+1]までの輪郭が、1区間にあるとき
-      w1 = (i_ed - i_st + 1) * 0.05 + 0.5;
-      //探索区間の決定
-      st = Math.floor(i_st+w1);
-      ed = Math.floor(i_ed - w1);
-    }else{
-      //頂点[i]から頂点[i+1]までの輪郭が、2区間に分かれているとき
-      w1 = ((i_ed+i_cood_num-i_st+1)%i_cood_num) * 0.05 + 0.5;
-      //探索区間の決定
-      st = (Math.floor(i_st+w1))%i_cood_num;
-      ed = (Math.floor(i_ed+i_cood_num-w1))%i_cood_num;
-    }
-    //探索区間数を確認
-    if(st<=ed){
-      //探索区間は1区間
-      n = ed - st + 1;
-      this._dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, st, n,this._xpos,this._ypos,0);
-    }else{
-      //探索区間は2区間
-      n=ed+1+i_cood_num-st;
-      this._dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, st,i_cood_num-st,this._xpos,this._ypos,0);
-      this._dist_factor.observ2IdealBatch(i_xcoord, i_ycoord, 0,ed+1,this._xpos,this._ypos,i_cood_num-st);
-    }
-    //要素数の確認
-    if (n < 2) {
-      // nが2以下でmatrix.PCAを計算することはできないので、エラー
-      return false;
-    }
-    //主成分分析する。
-    var evec=this.__getSquareLine_evec;
-    var mean=this.__getSquareLine_mean;
-    this._pca.pca(this._xpos,this._ypos,n,evec, this.__getSquareLine_ev,mean);
-    o_line.dy = evec.m01;// line[i][0] = evec->m[1];
-    o_line.dx = -evec.m00;// line[i][1] = -evec->m[0];
-    o_line.c = -(o_line.dy * mean[0] + o_line.dx * mean[1]);// line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]);
-    return true;
-  }
-})
-
-/**
- * get_vertex関数を切り離すためのクラス
- *
- */
-NyARVertexCounter = ASKlass('NyARVertexCounter',
-{
-  vertex : new IntVector(10),// 6まで削れる
-  number_of_vertex : 0,
-  thresh : 0,
-  x_coord : null,
-  y_coord : null,
-  getVertex : function(i_x_coord, i_y_coord,i_coord_len,st,ed,i_thresh)
-  {
-    this.number_of_vertex = 0;
-    this.thresh = i_thresh;
-    this.x_coord = i_x_coord;
-    this.y_coord = i_y_coord;
-    return this.get_vertex(st, ed,i_coord_len);
-  }
-  /**
-  * static int get_vertex( int x_coord[], int y_coord[], int st, int ed,double thresh, int vertex[], int *vnum) 関数の代替関数
-  *
-  * @param x_coord
-  * @param y_coord
-  * @param st
-  * @param ed
-  * @param thresh
-  * @return
-  */
-  ,get_vertex : function(st,ed,i_coord_len)
-  {
-    var i;
-    var d;
-    //メモ:座標値は65536を超えなければint32で扱って大丈夫なので変更。
-    //dmaxは4乗なのでやるとしてもint64じゃないとマズイ
-    var v1 = 0;
-    var lx_coord = this.x_coord;
-    var ly_coord = this.y_coord;
-    var a = ly_coord[ed] - ly_coord[st];
-    var b = lx_coord[st] - lx_coord[ed];
-    var c = lx_coord[ed] * ly_coord[st] - ly_coord[ed] * lx_coord[st];
-    var dmax = 0;
-    if(st<ed){
-      //stとedが1区間
-      for (i = st + 1; i < ed; i++) {
-        d = a * lx_coord[i] + b * ly_coord[i] + c;
-        if (d * d > dmax) {
-          dmax = d * d;
-          v1 = i;
-        }
-      }
-    }else{
-      //stとedが2区間
-      for (i = st + 1; i < i_coord_len; i++) {
-        d = a * lx_coord[i] + b * ly_coord[i] + c;
-        if (d * d > dmax) {
-          dmax = d * d;
-          v1 = i;
-        }
-      }
-      for (i = 0; i < ed; i++) {
-        d = a * lx_coord[i] + b * ly_coord[i] + c;
-        if (d * d > dmax) {
-          dmax = d * d;
-          v1 = i;
-        }
-      }
-    }
-    if (dmax / (a * a + b * b) > this.thresh) {
-      if (!this.get_vertex(st, v1,i_coord_len)) {
-        return false;
-      }
-      if (this.number_of_vertex > 5) {
-        return false;
-      }
-      this.vertex[this.number_of_vertex] = v1;// vertex[(*vnum)] = v1;
-      this.number_of_vertex++;// (*vnum)++;
-      if (!this.get_vertex(v1, ed,i_coord_len)) {
-        return false;
-      }
-    }
-    return true;
-  }
-})
-
-NyARCoord2SquareVertexIndexes = ASKlass('NyARCoord2SquareVertexIndexes',
-{
-  VERTEX_FACTOR : 1.0,// 線検出のファクタ
-  __getSquareVertex_wv1 : new NyARVertexCounter(),
-  __getSquareVertex_wv2 : new NyARVertexCounter(),
-  NyARCoord2SquareVertexIndexes : function()
-  {
-    return;
-  }
-  /**
-   * 座標集合から、頂点候補になりそうな場所を４箇所探して、そのインデクス番号を返します。
-   * @param i_x_coord
-   * @param i_y_coord
-   * @param i_coord_num
-   * @param i_area
-   * @param o_vertex
-   * @return
-   */
-  ,getVertexIndexes : function(i_x_coord ,i_y_coord,i_coord_num, i_area,o_vertex)
-  {
-    var wv1 = this.__getSquareVertex_wv1;
-    var wv2 = this.__getSquareVertex_wv2;
-    var vertex1_index=this.getFarPoint(i_x_coord,i_y_coord,i_coord_num,0);
-    var prev_vertex_index=(vertex1_index+i_coord_num)%i_coord_num;
-    var v1=this.getFarPoint(i_x_coord,i_y_coord,i_coord_num,vertex1_index);
-    var thresh = (i_area / 0.75) * 0.01 * this.VERTEX_FACTOR;
-    o_vertex[0] = vertex1_index;
-    if (!wv1.getVertex(i_x_coord, i_y_coord,i_coord_num, vertex1_index, v1, thresh)) {
-      return false;
-    }
-    if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v1,prev_vertex_index, thresh)) {
-      return false;
-    }
-    var v2;
-    if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
-      o_vertex[1] = wv1.vertex[0];
-      o_vertex[2] = v1;
-      o_vertex[3] = wv2.vertex[0];
-    } else if (wv1.number_of_vertex > 1 && wv2.number_of_vertex == 0) {
-      //頂点位置を、起点から対角点の間の1/2にあると予想して、検索する。
-      if(v1>=vertex1_index){
-        v2 = (v1-vertex1_index)/2+vertex1_index;
-      }else{
-        v2 = ((v1+i_coord_num-vertex1_index)/2+vertex1_index)%i_coord_num;
-      }
-      if (!wv1.getVertex(i_x_coord, i_y_coord,i_coord_num, vertex1_index, v2, thresh)) {
-        return false;
-      }
-      if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v2, v1, thresh)) {
-        return false;
-      }
-      if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
-        o_vertex[1] = wv1.vertex[0];
-        o_vertex[2] = wv2.vertex[0];
-        o_vertex[3] = v1;
-      } else {
-        return false;
-      }
-    } else if (wv1.number_of_vertex == 0 && wv2.number_of_vertex > 1) {
-      //v2 = (v1+ end_of_coord)/2;
-      if(v1<=prev_vertex_index){
-        v2 = (v1+prev_vertex_index)/2;
-      }else{
-        v2 = ((v1+i_coord_num+prev_vertex_index)/2)%i_coord_num;
-      }
-      if (!wv1.getVertex(i_x_coord, i_y_coord,i_coord_num, v1, v2, thresh)) {
-        return false;
-      }
-      if (!wv2.getVertex(i_x_coord, i_y_coord,i_coord_num, v2, prev_vertex_index, thresh)) {
-        return false;
-      }
-      if (wv1.number_of_vertex == 1 && wv2.number_of_vertex == 1) {
-        o_vertex[1] = v1;
-        o_vertex[2] = wv1.vertex[0];
-        o_vertex[3] = wv2.vertex[0];
-      } else {
-        return false;
-      }
-    } else {
-      return false;
-    }
-    return true;
-  }
-  /**
-   * i_pointの輪郭座標から、最も遠方にある輪郭座標のインデクスを探します。
-   * @param i_xcoord
-   * @param i_ycoord
-   * @param i_coord_num
-   * @return
-   */
-  ,getFarPoint : function(i_coord_x,i_coord_y,i_coord_num,i_point)
-  {
-    //
-    var sx = i_coord_x[i_point];
-    var sy = i_coord_y[i_point];
-    var d = 0;
-    var w, x, y;
-    var ret = 0;
-    var i;
-    for (i = i_point+1; i < i_coord_num; i++) {
-      x = i_coord_x[i] - sx;
-      y = i_coord_y[i] - sy;
-      w = x * x + y * y;
-      if (w > d) {
-        d = w;
-        ret = i;
-      }
-    }
-    for (i= 0; i < i_point; i++) {
-      x = i_coord_x[i] - sx;
-      y = i_coord_y[i] - sy;
-      w = x * x + y * y;
-      if (w > d) {
-        d = w;
-        ret = i;
-      }
-    }
-    return ret;
-  }
-})
-
-
-/**
- * ARMarkerInfoに相当するクラス。 矩形情報を保持します。
- *
- */
-NyARSquare = ASKlass('NyARSquare',
-{
-  line : NyARLinear.createArray(4),
-  sqvertex : NyARDoublePoint2d.createArray(4),
-  getCenter2d : function(o_out)
-  {
-    o_out.x=(this.sqvertex[0].x+this.sqvertex[1].x+this.sqvertex[2].x+this.sqvertex[3].x)/4;
-    o_out.y=(this.sqvertex[0].y+this.sqvertex[1].y+this.sqvertex[2].y+this.sqvertex[3].y)/4;
-    return;
-  }
-})
-NyARSquareContourDetector = ASKlass('NyARSquareContourDetector',
-{
-  /**
-   *
-   * @param i_raster
-   * @param i_callback
-   * @throws NyARException
-   */
-  detectMarkerCB : function(i_raster, i_callback)
-  {
-    NyARException.trap("getRgbPixelReader not implemented.");
-  }
-})
-NyARSquareContourDetector_IDetectMarkerCallback = ASKlass('NyARSquareContourDetector_IDetectMarkerCallback',
-{
-  onSquareDetect : function(i_sender,i_coordx,i_coordy,i_coor_num,i_vertex_index){}
-})
-RleLabelOverlapChecker = ASKlass('RleLabelOverlapChecker', NyARLabelOverlapChecker,
-{
-  RleLabelOverlapChecker : function(i_max_label)
-  {
-    NyARLabelOverlapChecker.initialize.call(this,i_max_label);
-  }
-  ,createArray : function(i_length)
-  {
-    return new Array(i_length);
-  }
-})
-NyARSquareContourDetector_Rle = ASKlass('NyARSquareContourDetector_Rle', NyARSquareContourDetector,
-{
-  AR_AREA_MAX : 100000,// #define AR_AREA_MAX 100000
-  AR_AREA_MIN : 70,// #define AR_AREA_MIN 70
-  _width : 0,
-  _height : 0,
-  _labeling : null,
-  _overlap_checker : new RleLabelOverlapChecker(32),
-  _cpickup : new NyARContourPickup(),
-  _stack : null,
-  _coord2vertex : new NyARCoord2SquareVertexIndexes(),
-  _max_coord : 0,
-  _xcoord : null,
-  _ycoord : null,
-  /**
-   * 最大i_squre_max個のマーカーを検出するクラスを作成する。
-   *
-   * @param i_param
-   */
-  NyARSquareContourDetector_Rle : function(i_size)
-  {
-    this._width = i_size.w;
-    this._height = i_size.h;
-    //ラベリングのサイズを指定したいときはsetAreaRangeを使ってね。
-    this._labeling = new NyARLabeling_Rle(this._width,this._height);
-    this._labeling.setAreaRange(this.AR_AREA_MAX, this.AR_AREA_MIN);
-    this._stack=new NyARRleLabelFragmentInfoStack(i_size.w*i_size.h*2048/(320*240)+32);//検出可能な最大ラベル数
-    // 輪郭の最大長は画面に映りうる最大の長方形サイズ。
-    var number_of_coord= (this._width + this._height) * 2;
-    // 輪郭バッファ
-    this._max_coord = number_of_coord;
-    this._xcoord = new IntVector(number_of_coord);
-    this._ycoord = new IntVector(number_of_coord);
-    return;
-  },
-  __detectMarker_mkvertex : new IntVector(4)
-  ,detectMarkerCB : function(i_raster ,i_callback)
-  {
-    var flagment=this._stack;
-    var overlap = this._overlap_checker;
-    // ラベル数が0ならここまで
-    var label_num=this._labeling.labeling_NyARBinRaster(i_raster, 0, i_raster.getHeight(), flagment);
-    if (label_num < 1) {
-      return;
-    }
-    //ラベルをソートしておく
-    flagment.sortByArea();
-    //ラベルリストを取得
-    var labels=(flagment.getArray());
-    var xsize = this._width;
-    var ysize = this._height;
-    var xcoord = this._xcoord;
-    var ycoord = this._ycoord;
-    var coord_max = this._max_coord;
-    var mkvertex =this.__detectMarker_mkvertex;
-    //重なりチェッカの最大数を設定
-    overlap.setMaxLabels(label_num);
-    for (var i=0; i < label_num; i++) {
-      var label_pt=labels[i];
-      var label_area = label_pt.area;
-      // クリップ領域が画面の枠に接していれば除外
-      if (label_pt.clip_l == 0 || label_pt.clip_r == xsize-1){
-        continue;
-      }
-      if (label_pt.clip_t == 0 || label_pt.clip_b == ysize-1){
-        continue;
-      }
-      // 既に検出された矩形との重なりを確認
-      if (!overlap.check(label_pt)) {
-        // 重なっているようだ。
-        continue;
-      }
-      //輪郭を取得
-      var coord_num = _cpickup.getContour_NyARBinRaster(i_raster,label_pt.entry_x,label_pt.clip_t, coord_max, xcoord, ycoord);
-      if (coord_num == coord_max) {
-        // 輪郭が大きすぎる。
-        continue;
-      }
-      //輪郭線をチェックして、矩形かどうかを判定。矩形ならばmkvertexに取得
-      if (!this._coord2vertex.getVertexIndexes(xcoord, ycoord,coord_num,label_area, mkvertex)) {
-        // 頂点の取得が出来なかった
-        continue;
-      }
-      //矩形を発見したことをコールバック関数で通知
-      i_callback.onSquareDetect(this,xcoord,ycoord,coord_num,mkvertex);
-      // 検出済の矩形の属したラベルを重なりチェックに追加する。
-      overlap.push(label_pt);
-    }
-    return;
-  }
-})
-NyARSquareStack = ASKlass('NyARSquareStack', NyARObjectStack,
-{
-  NyARSquareStack : function(i_length)
-  {
-    NyARObjectStack.initialize.call(this,i_length);
-  }
-  ,createArray : function(i_length)
-  {
-    var ret= new Array(i_length);
-    for (var i =0; i < i_length; i++){
-      ret[i] = new NyARSquare();
-    }
-    return (ret);
-  }
-})
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * PROJECT: FLARToolKit
- * --------------------------------------------------------------------------------
- * This work is based on the NyARToolKit developed by
- *   R.Iizuka (nyatla)
- * http://nyatla.jp/nyatoolkit/
- *
- * The FLARToolKit is ActionScript 3.0 version ARToolkit class library.
- * Copyright (C)2008 Saqoosha
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  http://www.libspark.org/wiki/saqoosha/FLARToolKit
- *  <saq(at)saqoosha.net>
- *
- */
-FLARSquare = NyARSquare;
-Cxdir = new IntVector([0,1,1,1,0,-1,-1,-1]);
-Cydir = new IntVector([-1,-1,0,1,1,1,0,-1]);
-FLContourPickup = ASKlass('FLContourPickup', NyARContourPickup,
-{
-  FLContourPickup : function()
-  {
-  }
-  ,getContour_FLARBinRaster : function(i_raster,i_entry_x,i_entry_y,i_array_size,o_coord_x,o_coord_y)
-  {
-    var xdir = this._getContour_xdir;// static int xdir[8] = { 0, 1, 1, 1, 0,-1,-1,-1};
-    var ydir = this._getContour_ydir;// static int ydir[8] = {-1,-1, 0, 1, 1, 1, 0,-1};
-    var i_buf=i_raster.getBuffer();
-    var width=i_raster.getWidth();
-    var height=i_raster.getHeight();
-    //クリップ領域の上端に接しているポイントを得る。
-    var coord_num = 1;
-    o_coord_x[0] = i_entry_x;
-    o_coord_y[0] = i_entry_y;
-    var dir = 5;
-    var c = i_entry_x;
-    var r = i_entry_y;
-    for (;;) {
-      dir = (dir + 5) % 8;//dirの正規化
-      //ここは頑張ればもっと最適化できると思うよ。
-      //4隅以外の境界接地の場合に、境界チェックを省略するとかね。
-      if(c>=1 && c<width-1 && r>=1 && r<height-1){
-        for(;;){//gotoのエミュレート用のfor文
-          //境界に接していないとき(暗点判定)
-          if (i_buf.getPixel(c + xdir[dir], r + ydir[dir]) >0) {
-            break;
-          }
-          dir++;
-          if (i_buf.getPixel(c + xdir[dir], r + ydir[dir]) >0) {
-            break;
-          }
-          dir++;
-          if (i_buf.getPixel(c + xdir[dir], r + ydir[dir]) >0) {
-            break;
-          }
-          dir++;
-          if (i_buf.getPixel(c + xdir[dir], r + ydir[dir]) >0) {
-            break;
-          }
-          dir++;
-          if (i_buf.getPixel(c + xdir[dir], r + ydir[dir]) >0) {
-            break;
-          }
-          dir++;
-          if (i_buf.getPixel(c + xdir[dir], r + ydir[dir]) >0) {
-            break;
-          }
-          dir++;
-          if (i_buf.getPixel(c + xdir[dir], r + ydir[dir]) >0) {
-            break;
-          }
-          dir++;
-          if (i_buf.getPixel(c + xdir[dir], r + ydir[dir]) >0) {
-            break;
-          }
-          //8方向全て調べたけどラベルが無いよ？
-          return -1;
-        }
-      }else{
-        //境界に接しているとき
-        var i;
-        for (i = 0; i < 8; i++){
-          var x=c + xdir[dir];
-          var y=r + ydir[dir];
-          //境界チェック
-          if(x>=0 && x<width && y>=0 && y<height){
-            if (i_buf.getPixel(y, x) >0) {
-              break;
-            }
-          }
-          dir++;//倍長テーブルを参照するので問題なし
-        }
-        if (i == 8) {
-          //8方向全て調べたけどラベルが無いよ？
-          return -1;
-        }
-      }
-      dir=dir% 8;//dirの正規化
-      // xcoordとycoordをc,rにも保存
-      c = c + xdir[dir];
-      r = r + ydir[dir];
-      o_coord_x[coord_num] = c;
-      o_coord_y[coord_num] = r;
-      // 終了条件判定
-      if (c == i_entry_x && r == i_entry_y){
-        coord_num++;
-        break;
-      }
-      coord_num++;
-      if (coord_num == i_array_size) {
-        //輪郭が末端に達した
-        return coord_num;
-      }
-    }
-    return coord_num;
-  }
-})
-
-FLARSquareContourDetector = ASKlass('FLARSquareContourDetector', NyARSquareContourDetector,
-{
-  AR_AREA_MAX : 100000// #define AR_AREA_MAX 100000
-  ,AR_AREA_MIN : 70// #define AR_AREA_MIN 70
-  ,_width : 0
-  ,_height : 0
-  ,_labeling : null
-  ,_overlap_checker : new NyARLabelOverlapChecker(32)
-  ,_cpickup : new FLContourPickup()
-  ,_stack : null
-  ,_coord2vertex : new NyARCoord2SquareVertexIndexes()
-  ,_max_coord : 0
-  ,_xcoord : null
-  ,_ycoord : null
-  /**
-   * 最大i_squre_max個のマーカーを検出するクラスを作成する。
-   *
-   * @param i_param
-   */
-  ,FLARSquareContourDetector : function(i_size)
-  {
-    this._width = i_size.w;
-    this._height = i_size.h;
-    //ラベリングのサイズを指定したいときはsetAreaRangeを使ってね。
-    this._labeling = new NyARLabeling_Rle(this._width,this._height);
-    this._stack=new NyARRleLabelFragmentInfoStack(i_size.w*i_size.h*2048/(320*240)+32);//検出可能な最大ラベル数
-    // 輪郭の最大長は画面に映りうる最大の長方形サイズ。
-    var number_of_coord= (this._width + this._height) * 2;
-    // 輪郭バッファ
-    this._max_coord = number_of_coord;
-    this._xcoord = new IntVector(number_of_coord);
-    this._ycoord = new IntVector(number_of_coord);
-    return;
-  }
-  /**
-   * 白領域の検査対象サイズ
-   *  最大サイズは 一辺約320px、最小サイズは 一辺約 8px まで解析対象としている
-   *  解析画像中で上記範囲内であれば解析対象となるが、最小サイズは小さすぎて意味をなさない。
-   *
-   * @param i_max 解析対象とする白領域の最大pixel数(一辺の二乗)
-   * @param i_min 解析対象とする白領域の最小pixel数(一辺の二乗)
-   */
-  ,setAreaRange : function(i_max, i_min)
-  {
-    this._labeling.setAreaRange(i_max, i_min);
-  }
-  ,__detectMarker_mkvertex : new IntVector(4)
-  ,detectMarkerCB : function(i_raster ,i_callback)
-  {
-    var flagment=this._stack;
-    var overlap = this._overlap_checker;
-    // ラベル数が0ならここまで
-    var label_num=this._labeling.labeling(i_raster, flagment);
-    if (label_num < 1) {
-      return;
-    }
-    //ラベルをソートしておく
-    flagment.sortByArea();
-    //ラベルリストを取得
-    var labels=flagment.getArray();
-    var xsize = this._width;
-    var ysize = this._height;
-    var xcoord = this._xcoord;
-    var ycoord = this._ycoord;
-    var coord_max = this._max_coord;
-    var mkvertex =this.__detectMarker_mkvertex;
-    //重なりチェッカの最大数を設定
-    overlap.setMaxLabels(label_num);
-    for (var i=0; i < label_num; i++) {
-      var label_pt=labels[i];
-      var label_area = label_pt.area;
-      // クリップ領域が画面の枠に接していれば除外
-      if (label_pt.clip_l == 0 || label_pt.clip_r == xsize-1){
-        continue;
-      }
-      if (label_pt.clip_t == 0 || label_pt.clip_b == ysize-1){
-        continue;
-      }
-      // 既に検出された矩形との重なりを確認
-      if (!overlap.check(label_pt)) {
-        // 重なっているようだ。
-        continue;
-      }
-      if (window.DEBUG) {
-        var cv = document.getElementById('debugCanvas').getContext('2d');
-        cv.strokeStyle = 'red';
-        cv.strokeRect(label_pt.clip_l, label_pt.clip_t, label_pt.clip_r-label_pt.clip_l, label_pt.clip_b-label_pt.clip_t);
-        cv.fillStyle = 'red';
-        cv.fillRect(label_pt.entry_x-1, label_pt.clip_t-1, 3,3);
-        cv.fillStyle = 'cyan';
-        cv.fillRect(label_pt.pos_x-1, label_pt.pos_y-1, 3,3);
-      }
-      //輪郭を取得
-      var coord_num = this._cpickup.getContour_FLARBinRaster(i_raster,label_pt.entry_x,label_pt.clip_t, coord_max, xcoord, ycoord);
-      if (coord_num == -1) return -1;
-      if (coord_num == coord_max) {
-        // 輪郭が大きすぎる。
-        continue;
-      }
-      //輪郭線をチェックして、矩形かどうかを判定。矩形ならばmkvertexに取得
-      var v = this._coord2vertex.getVertexIndexes(xcoord, ycoord,coord_num,label_area, mkvertex);
-      if (!v) {
-        // 頂点の取得が出来なかった
-        continue;
-      }
-      //矩形を発見したことをコールバック関数で通知
-      i_callback.onSquareDetect(this,xcoord,ycoord,coord_num,mkvertex);
-      // 検出済の矩形の属したラベルを重なりチェックに追加する。
-      overlap.push(label_pt);
-    }
-    return;
-  }
-})
-
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * JSARToolkit
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- *   Hirokazu Kato
- *   Mark Billinghurst
- *   HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * And the NyARToolkitAS3 ARToolKit class library.
- *   Copyright (C)2010 Ryo Iizuka
- *
- * JSARToolkit is a JavaScript port of NyARToolkitAS3.
- *   Copyright (C)2010 Ilmari Heikkinen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  ilmari.heikkinen@gmail.com
- *
- */
-
-
-/**
- * This class calculates ARMatrix from square information. -- 変換行列を計算するクラス。
- *
- */
-INyARTransMat = Klass( {
-  transMat : function(i_square,i_offset, o_result ){},
-  transMatContinue : function(i_square,i_offset ,io_result_conv){}
-})
-
-/**
- * 矩形の頂点情報を格納します。
- */
-NyARRectOffset = ASKlass('NyARRectOffset', {
-
-  vertex : NyARDoublePoint3d.createArray(4),
-  createArray : function(i_number)
-  {
-    var ret=new Array(i_number);
-    for(var i=0;i<i_number;i++)
-    {
-      ret[i]=new NyARRectOffset();
-    }
-    return ret;
-  },
-
-  /**
-  * 中心位置と辺長から、オフセット情報を作成して設定する。
-  * @param i_width
-  */
-  setSquare : function(i_width)
-  {
-    var w_2 = i_width / 2.0;
-    var vertex3d_ptr;
-    vertex3d_ptr= this.vertex[0];
-    vertex3d_ptr.x = -w_2;
-    vertex3d_ptr.y =  w_2;
-    vertex3d_ptr.z = 0.0;
-    vertex3d_ptr= this.vertex[1];
-    vertex3d_ptr.x = w_2;
-    vertex3d_ptr.y = w_2;
-    vertex3d_ptr.z = 0.0;
-    vertex3d_ptr= this.vertex[2];
-    vertex3d_ptr.x =  w_2;
-    vertex3d_ptr.y = -w_2;
-    vertex3d_ptr.z = 0.0;
-    vertex3d_ptr= this.vertex[3];
-    vertex3d_ptr.x = -w_2;
-    vertex3d_ptr.y = -w_2;
-    vertex3d_ptr.z = 0.0;
-    return;
-  }
-})
-
-
-
-
-
-
-
-/**
- * This class calculates ARMatrix from square information and holds it. --
- * 変換行列を計算して、結果を保持するクラス。
- *
- */
-NyARTransMat = ASKlass('NyARTransMat',INyARTransMat,
-{
-  _projection_mat_ref : null,
-  _rotmatrix : null,
-  _transsolver : null,
-  _mat_optimize : null,
-  _ref_dist_factor : null,
-  NyARTransMat : function(i_param)
-  {
-    var dist=i_param.getDistortionFactor();
-    var pmat=i_param.getPerspectiveProjectionMatrix();
-    this._transsolver=new NyARTransportVectorSolver(pmat,4);
-    //互換性が重要な時は、NyARRotMatrix_ARToolKitを使うこと。
-    //理屈はNyARRotMatrix_NyARToolKitもNyARRotMatrix_ARToolKitも同じだけど、少しだけ値がずれる。
-    this._rotmatrix = new NyARRotMatrix(pmat);
-    this._mat_optimize=new NyARPartialDifferentiationOptimize(pmat);
-    this._ref_dist_factor=dist;
-    this._projection_mat_ref=pmat;
-    this.__transMat_vertex_2d = NyARDoublePoint2d.createArray(4);
-    this.__transMat_vertex_3d = NyARDoublePoint3d.createArray(4);
-    this.__transMat_trans = new NyARDoublePoint3d();
-    this.__rot=new NyARDoubleMatrix33();
-  },
-  /**
-   * 頂点情報を元に、エラー閾値を計算します。
-   * @param i_vertex
-   */
-  makeErrThreshold : function(i_vertex)
-  {
-    var a,b,l1,l2;
-    a=i_vertex[0].x-i_vertex[2].x;
-    b=i_vertex[0].y-i_vertex[2].y;
-    l1=a*a+b*b;
-    a=i_vertex[1].x-i_vertex[3].x;
-    b=i_vertex[1].y-i_vertex[3].y;
-    l2=a*a+b*b;
-    return (Math.sqrt(l1>l2?l1:l2))/200;
-  },
-  /**
-   * double arGetTransMat( ARMarkerInfo *marker_info,double center[2], double width, double conv[3][4] )
-   *
-   * @param i_square
-   * 計算対象のNyARSquareオブジェクト
-   * @param i_direction
-   * @param i_width
-   * @return
-   * @throws NyARException
-   */
-  transMat : function(i_square,i_offset,o_result_conv)
-  {
-    var trans=this.__transMat_trans;
-    var err_threshold=this.makeErrThreshold(i_square.sqvertex);
-    //平行移動量計算機に、2D座標系をセット
-    var vertex_2d=this.__transMat_vertex_2d;
-    var vertex_3d=this.__transMat_vertex_3d;
-    this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d,4);
-    this._transsolver.set2dVertex(vertex_2d,4);
-    //回転行列を計算
-    this._rotmatrix.initRotBySquare(i_square.line,i_square.sqvertex);
-    //回転後の3D座標系から、平行移動量を計算
-    this._rotmatrix.getPoint3dBatch(i_offset.vertex,vertex_3d,4);
-    this._transsolver.solveTransportVector(vertex_3d,trans);
-    //計算結果の最適化(平行移動量と回転行列の最適化)
-    o_result_conv.error=this.optimize(this._rotmatrix, trans, this._transsolver,i_offset.vertex, vertex_2d,err_threshold);
-    // マトリクスの保存
-    this.updateMatrixValue(this._rotmatrix, trans,o_result_conv);
-    return;
-  },
-  /*
-   * (non-Javadoc)
-   * @see jp.nyatla.nyartoolkit.core.transmat.INyARTransMat#transMatContinue(jp.nyatla.nyartoolkit.core.NyARSquare, int, double, jp.nyatla.nyartoolkit.core.transmat.NyARTransMatResult)
-   */
-  transMatContinue : function(i_square,i_offset,o_result_conv)
-  {
-    var trans=this.__transMat_trans;
-    // io_result_convが初期値なら、transMatで計算する。
-    if (!o_result_conv.has_value) {
-      this.transMat(i_square,i_offset, o_result_conv);
-      return;
-    }
-    //最適化計算の閾値を決定
-    var err_threshold=this.makeErrThreshold(i_square.sqvertex);
-    //平行移動量計算機に、2D座標系をセット
-    var vertex_2d=this.__transMat_vertex_2d;
-    var vertex_3d=this.__transMat_vertex_3d;
-    this._ref_dist_factor.ideal2ObservBatch(i_square.sqvertex, vertex_2d,4);
-    this._transsolver.set2dVertex(vertex_2d,4);
-    //回転行列を計算
-    this._rotmatrix.initRotByPrevResult(o_result_conv);
-    //回転後の3D座標系から、平行移動量を計算
-    this._rotmatrix.getPoint3dBatch(i_offset.vertex,vertex_3d,4);
-    this._transsolver.solveTransportVector(vertex_3d,trans);
-    //現在のエラーレートを計算しておく
-    var min_err=this.errRate(this._rotmatrix,trans,i_offset.vertex, vertex_2d,4,vertex_3d);
-    var rot=this.__rot;
-    //エラーレートが前回のエラー値より閾値分大きかったらアゲイン
-    if(min_err<o_result_conv.error+err_threshold){
-      rot.setValue_NyARDoubleMatrix33(this._rotmatrix);
-      //最適化してみる。
-      for (var i = 0;i<5; i++) {
-        //変換行列の最適化
-        this._mat_optimize.modifyMatrix(rot, trans, i_offset.vertex, vertex_2d, 4);
-        var err=this.errRate(rot,trans,i_offset.vertex, vertex_2d,4,vertex_3d);
-        //System.out.println("E:"+err);
-        if(min_err-err<err_threshold/2){
-          //System.out.println("BREAK");
-          break;
-        }
-        this._transsolver.solveTransportVector(vertex_3d, trans);
-        this._rotmatrix.setValue_NyARDoubleMatrix33(rot);
-        min_err=err;
-      }
-      this.updateMatrixValue(this._rotmatrix,  trans,o_result_conv);
-    }else{
-      //回転行列を計算
-      this._rotmatrix.initRotBySquare(i_square.line,i_square.sqvertex);
-      //回転後の3D座標系から、平行移動量を計算
-      this._rotmatrix.getPoint3dBatch(i_offset.vertex,vertex_3d,4);
-      this._transsolver.solveTransportVector(vertex_3d,trans);
-      //計算結果の最適化(平行移動量と回転行列の最適化)
-      min_err=this.optimize(this._rotmatrix, trans, this._transsolver,i_offset.vertex, vertex_2d,err_threshold);
-      this.updateMatrixValue(this._rotmatrix, trans,o_result_conv);
-    }
-    o_result_conv.error=min_err;
-    return;
-  },
-
-  optimize : function(io_rotmat,io_transvec,i_solver,i_offset_3d,i_2d_vertex,i_err_threshold)
-  {
-    //System.out.println("START");
-    var vertex_3d=this.__transMat_vertex_3d;
-    //初期のエラー値を計算
-    var min_err=this.errRate(io_rotmat, io_transvec, i_offset_3d, i_2d_vertex,4,vertex_3d);
-    var rot=this.__rot;
-    rot.setValue_NyARDoubleMatrix33(io_rotmat);
-    for (var i = 0;i<5; i++) {
-      //変換行列の最適化
-      this._mat_optimize.modifyMatrix(rot, io_transvec, i_offset_3d, i_2d_vertex, 4);
-      var err=this.errRate(rot,io_transvec, i_offset_3d, i_2d_vertex,4,vertex_3d);
-      //System.out.println("E:"+err);
-      if(min_err-err<i_err_threshold){
-        //System.out.println("BREAK");
-        break;
-      }
-      i_solver.solveTransportVector(vertex_3d, io_transvec);
-      io_rotmat.setValue_NyARDoubleMatrix33(rot);
-      min_err=err;
-    }
-    //System.out.println("END");
-    return min_err;
-  },
-  //エラーレート計算機
-  errRate : function(io_rot,i_trans,i_vertex3d,i_vertex2d,i_number_of_vertex,o_rot_vertex)
-  {
-    var cp = this._projection_mat_ref;
-    var cp00=cp.m00;
-    var cp01=cp.m01;
-    var cp02=cp.m02;
-    var cp11=cp.m11;
-    var cp12=cp.m12;
-    var err=0;
-    for(var i=0;i<i_number_of_vertex;i++){
-      var x3d,y3d,z3d;
-      o_rot_vertex[i].x=x3d=io_rot.m00*i_vertex3d[i].x+io_rot.m01*i_vertex3d[i].y+io_rot.m02*i_vertex3d[i].z;
-      o_rot_vertex[i].y=y3d=io_rot.m10*i_vertex3d[i].x+io_rot.m11*i_vertex3d[i].y+io_rot.m12*i_vertex3d[i].z;
-      o_rot_vertex[i].z=z3d=io_rot.m20*i_vertex3d[i].x+io_rot.m21*i_vertex3d[i].y+io_rot.m22*i_vertex3d[i].z;
-      x3d+=i_trans.x;
-      y3d+=i_trans.y;
-      z3d+=i_trans.z;
-      //射影変換
-      var x2d=x3d*cp00+y3d*cp01+z3d*cp02;
-      var y2d=y3d*cp11+z3d*cp12;
-      var h2d=z3d;
-      //エラーレート計算
-      var t1=i_vertex2d[i].x-x2d/h2d;
-      var t2=i_vertex2d[i].y-y2d/h2d;
-      err+=t1*t1+t2*t2;
-    }
-    return err/i_number_of_vertex;
-  },
-  /**
-   * パラメータで変換行列を更新します。
-   *
-   * @param i_rot
-   * @param i_off
-   * @param i_trans
-   */
-  updateMatrixValue : function(i_rot,i_trans,o_result)
-  {
-    o_result.m00=i_rot.m00;
-    o_result.m01=i_rot.m01;
-    o_result.m02=i_rot.m02;
-    o_result.m03=i_trans.x;
-    o_result.m10 =i_rot.m10;
-    o_result.m11 =i_rot.m11;
-    o_result.m12 =i_rot.m12;
-    o_result.m13 =i_trans.y;
-    o_result.m20 = i_rot.m20;
-    o_result.m21 = i_rot.m21;
-    o_result.m22 = i_rot.m22;
-    o_result.m23 = i_trans.z;
-    o_result.has_value = true;
-    return;
-  }
-})
-
-
-NyARTransMatResult = ASKlass('NyARTransMatResult', NyARDoubleMatrix34,
-{
-  /**
-   * エラーレート。この値はINyARTransMatの派生クラスが使います。
-   */
-  error : 0,
-  has_value : false,
-  /**
-   * この関数は、0-PIの間で値を返します。
-   * @param o_out
-   */
-  getZXYAngle : function(o_out)
-  {
-    var sina = this.m21;
-    if (sina >= 1.0) {
-      o_out.x = Math.PI / 2;
-      o_out.y = 0;
-      o_out.z = Math.atan2(-this.m10, this.m00);
-    } else if (sina <= -1.0) {
-      o_out.x = -Math.PI / 2;
-      o_out.y = 0;
-      o_out.z = Math.atan2(-this.m10, this.m00);
-    } else {
-      o_out.x = Math.asin(sina);
-      o_out.z = Math.atan2(-this.m01, this.m11);
-      o_out.y = Math.atan2(-this.m20, this.m22);
-    }
-  },
-  transformVertex_Number : function(i_x,i_y,i_z,o_out)
-  {
-    o_out.x=this.m00*i_x+this.m01*i_y+this.m02*i_z+this.m03;
-    o_out.y=this.m10*i_x+this.m11*i_y+this.m12*i_z+this.m13;
-    o_out.z=this.m20*i_x+this.m21*i_y+this.m22*i_z+this.m23;
-    return;
-  },
-  transformVertex_NyARDoublePoint3d : function(i_in,o_out)
-  {
-    this.transformVertex_Number(i_in.x,i_in.y,i_in.z,o_out);
-  }
-})
-
-
-
-
-
-/**
- * 基本姿勢と実画像を一致するように、角度を微調整→平行移動量を再計算 を繰り返して、変換行列を最適化する。
- *
- */
-NyARPartialDifferentiationOptimize = ASKlass('NyARPartialDifferentiationOptimize',
-{
-  _projection_mat_ref : null,
-  NyARPartialDifferentiationOptimize : function(i_projection_mat_ref)
-  {
-    this._projection_mat_ref = i_projection_mat_ref;
-    this.__angles_in=TSinCosValue.createArray(3);
-    this.__ang=new NyARDoublePoint3d();
-    this.__sin_table = new FloatVector(4);
-    return;
-  },
-  sincos2Rotation_ZXY : function(i_sincos,i_rot_matrix)
-  {
-    var sina = i_sincos[0].sin_val;
-    var cosa = i_sincos[0].cos_val;
-    var sinb = i_sincos[1].sin_val;
-    var cosb = i_sincos[1].cos_val;
-    var sinc = i_sincos[2].sin_val;
-    var cosc = i_sincos[2].cos_val;
-    i_rot_matrix.m00 = cosc * cosb - sinc * sina * sinb;
-    i_rot_matrix.m01 = -sinc * cosa;
-    i_rot_matrix.m02 = cosc * sinb + sinc * sina * cosb;
-    i_rot_matrix.m10 = sinc * cosb + cosc * sina * sinb;
-    i_rot_matrix.m11 = cosc * cosa;
-    i_rot_matrix.m12 = sinc * sinb - cosc * sina * cosb;
-    i_rot_matrix.m20 = -cosa * sinb;
-    i_rot_matrix.m21 = sina;
-    i_rot_matrix.m22 = cosb * cosa;
-  },
-  rotation2Sincos_ZXY : function(i_rot_matrix,o_out,o_ang)
-  {
-    var x, y, z;
-    var sina = i_rot_matrix.m21;
-    if (sina >= 1.0) {
-      x = Math.PI / 2;
-      y = 0;
-      z = Math.atan2(-i_rot_matrix.m10, i_rot_matrix.m00);
-    } else if (sina <= -1.0) {
-      x = -Math.PI / 2;
-      y = 0;
-      z = Math.atan2(-i_rot_matrix.m10, i_rot_matrix.m00);
-    } else {
-      x = Math.asin(sina);
-      y = Math.atan2(-i_rot_matrix.m20, i_rot_matrix.m22);
-      z = Math.atan2(-i_rot_matrix.m01, i_rot_matrix.m11);
-    }
-    o_ang.x=x;
-    o_ang.y=y;
-    o_ang.z=z;
-    o_out[0].sin_val = Math.sin(x);
-    o_out[0].cos_val = Math.cos(x);
-    o_out[1].sin_val = Math.sin(y);
-    o_out[1].cos_val = Math.cos(y);
-    o_out[2].sin_val = Math.sin(z);
-    o_out[2].cos_val = Math.cos(z);
-    return;
-  },
-  /*
-   * 射影変換式 基本式 ox=(cosc * cosb - sinc * sina * sinb)*ix+(-sinc * cosa)*iy+(cosc * sinb + sinc * sina * cosb)*iz+i_trans.x; oy=(sinc * cosb + cosc * sina *
-   * sinb)*ix+(cosc * cosa)*iy+(sinc * sinb - cosc * sina * cosb)*iz+i_trans.y; oz=(-cosa * sinb)*ix+(sina)*iy+(cosb * cosa)*iz+i_trans.z;
-   *
-   * double ox=(cosc * cosb)*ix+(-sinc * sina * sinb)*ix+(-sinc * cosa)*iy+(cosc * sinb)*iz + (sinc * sina * cosb)*iz+i_trans.x; double oy=(sinc * cosb)*ix
-   * +(cosc * sina * sinb)*ix+(cosc * cosa)*iy+(sinc * sinb)*iz+(- cosc * sina * cosb)*iz+i_trans.y; double oz=(-cosa * sinb)*ix+(sina)*iy+(cosb *
-   * cosa)*iz+i_trans.z;
-   *
-   * sina,cosaについて解く cx=(cp00*(-sinc*sinb*ix+sinc*cosb*iz)+cp01*(cosc*sinb*ix-cosc*cosb*iz)+cp02*(iy))*sina
-   * +(cp00*(-sinc*iy)+cp01*((cosc*iy))+cp02*(-sinb*ix+cosb*iz))*cosa
-   * +(cp00*(i_trans.x+cosc*cosb*ix+cosc*sinb*iz)+cp01*((i_trans.y+sinc*cosb*ix+sinc*sinb*iz))+cp02*(i_trans.z));
-   * cy=(cp11*(cosc*sinb*ix-cosc*cosb*iz)+cp12*(iy))*sina +(cp11*((cosc*iy))+cp12*(-sinb*ix+cosb*iz))*cosa
-   * +(cp11*((i_trans.y+sinc*cosb*ix+sinc*sinb*iz))+cp12*(i_trans.z)); ch=(iy)*sina +(-sinb*ix+cosb*iz)*cosa +i_trans.z; sinb,cosb hx=(cp00*(-sinc *
-   * sina*ix+cosc*iz)+cp01*(cosc * sina*ix+sinc*iz)+cp02*(-cosa*ix))*sinb +(cp01*(sinc*ix-cosc * sina*iz)+cp00*(cosc*ix+sinc * sina*iz)+cp02*(cosa*iz))*cosb
-   * +(cp00*(i_trans.x+(-sinc*cosa)*iy)+cp01*(i_trans.y+(cosc * cosa)*iy)+cp02*(i_trans.z+(sina)*iy)); double hy=(cp11*(cosc *
-   * sina*ix+sinc*iz)+cp12*(-cosa*ix))*sinb +(cp11*(sinc*ix-cosc * sina*iz)+cp12*(cosa*iz))*cosb +(cp11*(i_trans.y+(cosc *
-   * cosa)*iy)+cp12*(i_trans.z+(sina)*iy)); double h =((-cosa*ix)*sinb +(cosa*iz)*cosb +i_trans.z+(sina)*iy); パラメータ返還式 L=2*Σ(d[n]*e[n]+a[n]*b[n])
-   * J=2*Σ(d[n]*f[n]+a[n]*c[n])/L K=2*Σ(-e[n]*f[n]+b[n]*c[n])/L M=Σ(-e[n]^2+d[n]^2-b[n]^2+a[n]^2)/L 偏微分式 +J*cos(x) +K*sin(x) -sin(x)^2 +cos(x)^2
-   * +2*M*cos(x)*sin(x)
-   */
-  optimizeParamX : function(i_angle_y,i_angle_z,i_trans,i_vertex3d, i_vertex2d,i_number_of_vertex,i_hint_angle)
-  {
-    var cp = this._projection_mat_ref;
-    var sinb = i_angle_y.sin_val;
-    var cosb = i_angle_y.cos_val;
-    var sinc = i_angle_z.sin_val;
-    var cosc = i_angle_z.cos_val;
-    var L, J, K, M, N, O;
-    L = J = K = M = N = O = 0;
-    for (var i = 0; i < i_number_of_vertex; i++) {
-      var ix, iy, iz;
-      ix = i_vertex3d[i].x;
-      iy = i_vertex3d[i].y;
-      iz = i_vertex3d[i].z;
-      var cp00 = cp.m00;
-      var cp01 = cp.m01;
-      var cp02 = cp.m02;
-      var cp11 = cp.m11;
-      var cp12 = cp.m12;
-      var X0 = (cp00 * (-sinc * sinb * ix + sinc * cosb * iz) + cp01 * (cosc * sinb * ix - cosc * cosb * iz) + cp02 * (iy));
-      var X1 = (cp00 * (-sinc * iy) + cp01 * ((cosc * iy)) + cp02 * (-sinb * ix + cosb * iz));
-      var X2 = (cp00 * (i_trans.x + cosc * cosb * ix + cosc * sinb * iz) + cp01 * ((i_trans.y + sinc * cosb * ix + sinc * sinb * iz)) + cp02 * (i_trans.z));
-      var Y0 = (cp11 * (cosc * sinb * ix - cosc * cosb * iz) + cp12 * (iy));
-      var Y1 = (cp11 * ((cosc * iy)) + cp12 * (-sinb * ix + cosb * iz));
-      var Y2 = (cp11 * ((i_trans.y + sinc * cosb * ix + sinc * sinb * iz)) + cp12 * (i_trans.z));
-      var H0 = (iy);
-      var H1 = (-sinb * ix + cosb * iz);
-      var H2 = i_trans.z;
-      var VX = i_vertex2d[i].x;
-      var VY = i_vertex2d[i].y;
-      var a, b, c, d, e, f;
-      a = (VX * H0 - X0);
-      b = (VX * H1 - X1);
-      c = (VX * H2 - X2);
-      d = (VY * H0 - Y0);
-      e = (VY * H1 - Y1);
-      f = (VY * H2 - Y2);
-      L += d * e + a * b;
-      N += d * d + a * a;
-      J += d * f + a * c;
-      M += e * e + b * b;
-      K += e * f + b * c;
-      O += f * f + c * c;
-    }
-    L *=2;
-    J *=2;
-    K *=2;
-    return this.getMinimumErrorAngleFromParam(L,J, K, M, N, O, i_hint_angle);
-  },
-  optimizeParamY : function(i_angle_x,i_angle_z,i_trans,i_vertex3d,i_vertex2d,i_number_of_vertex,i_hint_angle)
-  {
-    var cp = this._projection_mat_ref;
-    var sina = i_angle_x.sin_val;
-    var cosa = i_angle_x.cos_val;
-    var sinc = i_angle_z.sin_val;
-    var cosc = i_angle_z.cos_val;
-    var L, J, K, M, N, O;
-    L = J = K = M = N = O = 0;
-    for (var i = 0; i < i_number_of_vertex; i++) {
-      var ix, iy, iz;
-      ix = i_vertex3d[i].x;
-      iy = i_vertex3d[i].y;
-      iz = i_vertex3d[i].z;
-      var cp00 = cp.m00;
-      var cp01 = cp.m01;
-      var cp02 = cp.m02;
-      var cp11 = cp.m11;
-      var cp12 = cp.m12;
-      var X0 = (cp00 * (-sinc * sina * ix + cosc * iz) + cp01 * (cosc * sina * ix + sinc * iz) + cp02 * (-cosa * ix));
-      var X1 = (cp01 * (sinc * ix - cosc * sina * iz) + cp00 * (cosc * ix + sinc * sina * iz) + cp02 * (cosa * iz));
-      var X2 = (cp00 * (i_trans.x + (-sinc * cosa) * iy) + cp01 * (i_trans.y + (cosc * cosa) * iy) + cp02 * (i_trans.z + (sina) * iy));
-      var Y0 = (cp11 * (cosc * sina * ix + sinc * iz) + cp12 * (-cosa * ix));
-      var Y1 = (cp11 * (sinc * ix - cosc * sina * iz) + cp12 * (cosa * iz));
-      var Y2 = (cp11 * (i_trans.y + (cosc * cosa) * iy) + cp12 * (i_trans.z + (sina) * iy));
-      var H0 = (-cosa * ix);
-      var H1 = (cosa * iz);
-      var H2 = i_trans.z + (sina) * iy;
-      var VX = i_vertex2d[i].x;
-      var VY = i_vertex2d[i].y;
-      var a, b, c, d, e, f;
-      a = (VX * H0 - X0);
-      b = (VX * H1 - X1);
-      c = (VX * H2 - X2);
-      d = (VY * H0 - Y0);
-      e = (VY * H1 - Y1);
-      f = (VY * H2 - Y2);
-      L += d * e + a * b;
-      N += d * d + a * a;
-      J += d * f + a * c;
-      M += e * e + b * b;
-      K += e * f + b * c;
-      O += f * f + c * c;
-    }
-    L *= 2;
-    J *= 2;
-    K *= 2;
-    return this.getMinimumErrorAngleFromParam(L,J, K, M, N, O, i_hint_angle);
-  },
-  optimizeParamZ : function(i_angle_x,i_angle_y,i_trans,i_vertex3d,i_vertex2d,i_number_of_vertex,i_hint_angle)
-  {
-    var cp = this._projection_mat_ref;
-    var sina = i_angle_x.sin_val;
-    var cosa = i_angle_x.cos_val;
-    var sinb = i_angle_y.sin_val;
-    var cosb = i_angle_y.cos_val;
-    var L, J, K, M, N, O;
-    L = J = K = M = N = O = 0;
-    for (var i = 0; i < i_number_of_vertex; i++) {
-      var ix, iy, iz;
-      ix = i_vertex3d[i].x;
-      iy = i_vertex3d[i].y;
-      iz = i_vertex3d[i].z;
-      var cp00 = cp.m00;
-      var cp01 = cp.m01;
-      var cp02 = cp.m02;
-      var cp11 = cp.m11;
-      var cp12 = cp.m12;
-      var X0 = (cp00 * (-sina * sinb * ix - cosa * iy + sina * cosb * iz) + cp01 * (ix * cosb + sinb * iz));
-      var X1 = (cp01 * (sina * ix * sinb + cosa * iy - sina * iz * cosb) + cp00 * (cosb * ix + sinb * iz));
-      var X2 = cp00 * i_trans.x + cp01 * (i_trans.y) + cp02 * (-cosa * sinb) * ix + cp02 * (sina) * iy + cp02 * ((cosb * cosa) * iz + i_trans.z);
-      var Y0 = cp11 * (ix * cosb + sinb * iz);
-      var Y1 = cp11 * (sina * ix * sinb + cosa * iy - sina * iz * cosb);
-      var Y2 = (cp11 * i_trans.y + cp12 * (-cosa * sinb) * ix + cp12 * ((sina) * iy + (cosb * cosa) * iz + i_trans.z));
-      var H0 = 0;
-      var H1 = 0;
-      var H2 = ((-cosa * sinb) * ix + (sina) * iy + (cosb * cosa) * iz + i_trans.z);
-      var VX = i_vertex2d[i].x;
-      var VY = i_vertex2d[i].y;
-      var a, b, c, d, e, f;
-      a = (VX * H0 - X0);
-      b = (VX * H1 - X1);
-      c = (VX * H2 - X2);
-      d = (VY * H0 - Y0);
-      e = (VY * H1 - Y1);
-      f = (VY * H2 - Y2);
-      L += d * e + a * b;
-      N += d * d + a * a;
-      J += d * f + a * c;
-      M += e * e + b * b;
-      K += e * f + b * c;
-      O += f * f + c * c;
-    }
-    L *=2;
-    J *=2;
-    K *=2;
-    return this.getMinimumErrorAngleFromParam(L,J, K, M, N, O, i_hint_angle);
-  },
-  modifyMatrix : function(io_rot,i_trans,i_vertex3d,i_vertex2d,i_number_of_vertex)
-  {
-    var angles_in = this.__angles_in;// x,y,z
-    var ang = this.__ang;
-    // ZXY系のsin/cos値を抽出
-    this.rotation2Sincos_ZXY(io_rot, angles_in,ang);
-    ang.x += this.optimizeParamX(angles_in[1], angles_in[2], i_trans, i_vertex3d, i_vertex2d, i_number_of_vertex, ang.x);
-    ang.y += this.optimizeParamY(angles_in[0], angles_in[2], i_trans, i_vertex3d, i_vertex2d, i_number_of_vertex, ang.y);
-    ang.z += this.optimizeParamZ(angles_in[0], angles_in[1], i_trans, i_vertex3d, i_vertex2d, i_number_of_vertex, ang.z);
-    io_rot.setZXYAngle_Number(ang.x, ang.y, ang.z);
-    return;
-  },
-  /**
-   * エラーレートが最小になる点を得る。
-   */
-  getMinimumErrorAngleFromParam : function(iL,iJ,iK,iM,iN,iO,i_hint_angle)
-  {
-    var sin_table = this.__sin_table;
-    var M = (iN - iM)/iL;
-    var J = iJ/iL;
-    var K = -iK/iL;
-    // パラメータからsinテーブルを作成
-    // (- 4*M^2-4)*x^4 + (4*K- 4*J*M)*x^3 + (4*M^2 -(K^2- 4)- J^2)*x^2 +(4*J*M- 2*K)*x + J^2-1 = 0
-    var number_of_sin = NyAREquationSolver.solve4Equation(-4 * M * M - 4, 4 * K - 4 * J * M, 4 * M * M - (K * K - 4) - J * J, 4 * J * M - 2 * K, J * J - 1, sin_table);
-    // 最小値２個を得ておく。
-    var min_ang_0 = Number.MAX_VALUE;
-    var min_ang_1 = Number.MAX_VALUE;
-    var min_err_0 = Number.MAX_VALUE;
-    var min_err_1 = Number.MAX_VALUE;
-    for (var i = 0; i < number_of_sin; i++) {
-      // +-cos_v[i]が頂点候補
-      var sin_rt = sin_table[i];
-      var cos_rt = Math.sqrt(1 - (sin_rt * sin_rt));
-      // cosを修復。微分式で0に近い方が正解
-      // 0 = 2*cos(x)*sin(x)*M - sin(x)^2 + cos(x)^2 + sin(x)*K + cos(x)*J
-      var a1 = 2 * cos_rt * sin_rt * M + sin_rt * (K - sin_rt) + cos_rt * (cos_rt + J);
-      var a2 = 2 * (-cos_rt) * sin_rt * M + sin_rt * (K - sin_rt) + (-cos_rt) * ((-cos_rt) + J);
-      // 絶対値になおして、真のcos値を得ておく。
-      a1 = a1 < 0 ? -a1 : a1;
-      a2 = a2 < 0 ? -a2 : a2;
-      cos_rt = (a1 < a2) ? cos_rt : -cos_rt;
-      var ang = Math.atan2(sin_rt, cos_rt);
-      // エラー値を計算
-      var err = iN * sin_rt * sin_rt + (iL*cos_rt + iJ) * sin_rt + iM * cos_rt * cos_rt + iK * cos_rt + iO;
-      // 最小の２個を獲得する。
-      if (min_err_0 > err) {
-        min_err_1 = min_err_0;
-        min_ang_1 = min_ang_0;
-        min_err_0 = err;
-        min_ang_0 = ang;
-      } else if (min_err_1 > err) {
-        min_err_1 = err;
-        min_ang_1 = ang;
-      }
-    }
-    // [0]をテスト
-    var gap_0;
-    gap_0 = min_ang_0 - i_hint_angle;
-    if (gap_0 > Math.PI) {
-      gap_0 = (min_ang_0 - Math.PI * 2) - i_hint_angle;
-    } else if (gap_0 < -Math.PI) {
-      gap_0 = (min_ang_0 + Math.PI * 2) - i_hint_angle;
-    }
-    // [1]をテスト
-    var gap_1;
-    gap_1 = min_ang_1 - i_hint_angle;
-    if (gap_1 > Math.PI) {
-      gap_1 = (min_ang_1 - Math.PI * 2) - i_hint_angle;
-    } else if (gap_1 < -Math.PI) {
-      gap_1 = (min_ang_1 + Math.PI * 2) - i_hint_angle;
-    }
-    return Math.abs(gap_1) < Math.abs(gap_0) ? gap_1 : gap_0;
-  }
-})
-
-TSinCosValue = ASKlass('TSinCosValue',{
-  cos_val : 0,
-  sin_val : 0,
-  createArray : function(i_size)
-  {
-    var result=new Array(i_size);
-    for(var i=0;i<i_size;i++){
-      result[i]=new TSinCosValue();
-    }
-    return result;
-  }
-})
-
-
-
-
-/**
- * 回転行列計算用の、3x3行列
- *
- */
-NyARRotMatrix = ASKlass('NyARRotMatrix',NyARDoubleMatrix33,
-{
-  /**
-   * インスタンスを準備します。
-   *
-   * @param i_param
-   */
-  NyARRotMatrix : function(i_matrix)
-  {
-    this.__initRot_vec1=new NyARRotVector(i_matrix);
-    this.__initRot_vec2=new NyARRotVector(i_matrix);
-    return;
-  },
-  __initRot_vec1 : null,
-  __initRot_vec2 : null,
-  /**
-   * NyARTransMatResultの内容からNyARRotMatrixを復元します。
-   * @param i_prev_result
-   */
-  initRotByPrevResult : function(i_prev_result)
-  {
-    this.m00=i_prev_result.m00;
-    this.m01=i_prev_result.m01;
-    this.m02=i_prev_result.m02;
-    this.m10=i_prev_result.m10;
-    this.m11=i_prev_result.m11;
-    this.m12=i_prev_result.m12;
-    this.m20=i_prev_result.m20;
-    this.m21=i_prev_result.m21;
-    this.m22=i_prev_result.m22;
-    return;
-  },
-  /**
-   *
-   * @param i_linear
-   * @param i_sqvertex
-   * @throws NyARException
-   */
-  initRotBySquare : function(i_linear, i_sqvertex)
-  {
-    var vec1=this.__initRot_vec1;
-    var vec2=this.__initRot_vec2;
-    //向かい合った辺から、２本のベクトルを計算
-    //軸１
-    vec1.exteriorProductFromLinear(i_linear[0], i_linear[2]);
-    vec1.checkVectorByVertex(i_sqvertex[0], i_sqvertex[1]);
-    //軸２
-    vec2.exteriorProductFromLinear(i_linear[1], i_linear[3]);
-    vec2.checkVectorByVertex(i_sqvertex[3], i_sqvertex[0]);
-    //回転の最適化？
-    NyARRotVector.checkRotation(vec1,vec2);
-    this.m00 =vec1.v1;
-    this.m10 =vec1.v2;
-    this.m20 =vec1.v3;
-    this.m01 =vec2.v1;
-    this.m11 =vec2.v2;
-    this.m21 =vec2.v3;
-    //最後の軸を計算
-    var w02 = vec1.v2 * vec2.v3 - vec1.v3 * vec2.v2;
-    var w12 = vec1.v3 * vec2.v1 - vec1.v1 * vec2.v3;
-    var w22 = vec1.v1 * vec2.v2 - vec1.v2 * vec2.v1;
-    var w = Math.sqrt(w02 * w02 + w12 * w12 + w22 * w22);
-    this.m02 = w02/w;
-    this.m12 = w12/w;
-    this.m22 = w22/w;
-    return;
-  },
-  /**
-   * i_in_pointを変換行列で座標変換する。
-   * @param i_in_point
-   * @param i_out_point
-   */
-  getPoint3d : function(i_in_point,i_out_point)
-  {
-    var x=i_in_point.x;
-    var y=i_in_point.y;
-    var z=i_in_point.z;
-    i_out_point.x=this.m00 * x + this.m01 * y + this.m02 * z;
-    i_out_point.y=this.m10 * x + this.m11 * y + this.m12 * z;
-    i_out_point.z=this.m20 * x + this.m21 * y + this.m22 * z;
-    return;
-  },
-  /**
-   * 複数の頂点を一括して変換する
-   * @param i_in_point
-   * @param i_out_point
-   * @param i_number_of_vertex
-   */
-  getPoint3dBatch : function(i_in_point,i_out_point,i_number_of_vertex)
-  {
-    for(var i=i_number_of_vertex-1;i>=0;i--){
-      var out_ptr =i_out_point[i];
-      var in_ptr=i_in_point[i];
-      var x=in_ptr.x;
-      var y=in_ptr.y;
-      var z=in_ptr.z;
-      out_ptr.x=this.m00 * x + this.m01 * y + this.m02 * z;
-      out_ptr.y=this.m10 * x + this.m11 * y + this.m12 * z;
-      out_ptr.z=this.m20 * x + this.m21 * y + this.m22 * z;
-    }
-    return;
-  }
-})
-
-
-
-
-NyARRotVector = ASKlass('NyARRotVector',
-{
-  //publicメンバ達
-  v1 : 0,
-  v2 : 0,
-  v3 : 0,
-  //privateメンバ達
-  _projection_mat_ref : null,
-  _inv_cpara_array_ref : null,
-  NyARRotVector : function(i_cmat)
-  {
-    var mat_a = new NyARMat(3, 3);
-    var a_array = mat_a.getArray();
-    a_array[0][0] =i_cmat.m00;
-    a_array[0][1] =i_cmat.m01;
-    a_array[0][2] =i_cmat.m02;
-    a_array[1][0] =i_cmat.m10;
-    a_array[1][1] =i_cmat.m11;
-    a_array[1][2] =i_cmat.m12;
-    a_array[2][0] =i_cmat.m20;
-    a_array[2][1] =i_cmat.m21;
-    a_array[2][2] =i_cmat.m22;
-    mat_a.matrixSelfInv();
-    this._projection_mat_ref = i_cmat;
-    this._inv_cpara_array_ref = mat_a.getArray();
-    //GCない言語のときは、ここで配列の所有権委譲してね！
-  },
-  /**
-   * ２直線に直交するベクトルを計算する・・・だと思う。
-   * @param i_linear1
-   * @param i_linear2
-   */
-  exteriorProductFromLinear : function(i_linear1,i_linear2)
-  {
-    //1行目
-    var cmat= this._projection_mat_ref;
-    var w1 = i_linear1.dy * i_linear2.dx - i_linear2.dy * i_linear1.dx;
-    var w2 = i_linear1.dx * i_linear2.c - i_linear2.dx * i_linear1.c;
-    var w3 = i_linear1.c * i_linear2.dy - i_linear2.c * i_linear1.dy;
-    var m0 = w1 * (cmat.m01 * cmat.m12 - cmat.m02 * cmat.m11) + w2 * cmat.m11 - w3 * cmat.m01;//w1 * (cpara[0 * 4 + 1] * cpara[1 * 4 + 2] - cpara[0 * 4 + 2] * cpara[1 * 4 + 1]) + w2 * cpara[1 * 4 + 1] - w3 * cpara[0 * 4 + 1];
-    var m1 = -w1 * cmat.m00 * cmat.m12 + w3 * cmat.m00;//-w1 * cpara[0 * 4 + 0] * cpara[1 * 4 + 2] + w3 * cpara[0 * 4 + 0];
-    var m2 = w1 * cmat.m00 * cmat.m11;//w1 * cpara[0 * 4 + 0] * cpara[1 * 4 + 1];
-    var w = Math.sqrt(m0 * m0 + m1 * m1 + m2 * m2);
-    this.v1 = m0 / w;
-    this.v2 = m1 / w;
-    this.v3 = m2 / w;
-    return;
-  },
-  /**
-   * static int check_dir( double dir[3], double st[2], double ed[2],double cpara[3][4] ) Optimize[526->468]
-   * ベクトルの開始/終了座標を指定して、ベクトルの方向を調整する。
-   * @param i_start_vertex
-   * @param i_end_vertex
-   * @param cpara
-   */
-  checkVectorByVertex : function(i_start_vertex, i_end_vertex)
-  {
-    var h;
-    var inv_cpara = this._inv_cpara_array_ref;
-    //final double[] world = __checkVectorByVertex_world;// [2][3];
-    var world0 = inv_cpara[0][0] * i_start_vertex.x * 10.0 + inv_cpara[0][1] * i_start_vertex.y * 10.0 + inv_cpara[0][2] * 10.0;// mat_a->m[0]*st[0]*10.0+
-    var world1 = inv_cpara[1][0] * i_start_vertex.x * 10.0 + inv_cpara[1][1] * i_start_vertex.y * 10.0 + inv_cpara[1][2] * 10.0;// mat_a->m[3]*st[0]*10.0+
-    var world2 = inv_cpara[2][0] * i_start_vertex.x * 10.0 + inv_cpara[2][1] * i_start_vertex.y * 10.0 + inv_cpara[2][2] * 10.0;// mat_a->m[6]*st[0]*10.0+
-    var world3 = world0 + this.v1;
-    var world4 = world1 + this.v2;
-    var world5 = world2 + this.v3;
-    // </Optimize>
-    //final double[] camera = __checkVectorByVertex_camera;// [2][2];
-    var cmat= this._projection_mat_ref;
-    //h = cpara[2 * 4 + 0] * world0 + cpara[2 * 4 + 1] * world1 + cpara[2 * 4 + 2] * world2;
-    h = cmat.m20 * world0 + cmat.m21 * world1 + cmat.m22 * world2;
-    if (h == 0.0) {
-      throw new NyARException();
-    }
-    //final double camera0 = (cpara[0 * 4 + 0] * world0 + cpara[0 * 4 + 1] * world1 + cpara[0 * 4 + 2] * world2) / h;
-    //final double camera1 = (cpara[1 * 4 + 0] * world0 + cpara[1 * 4 + 1] * world1 + cpara[1 * 4 + 2] * world2) / h;
-    var camera0 = (cmat.m00 * world0 + cmat.m01 * world1 + cmat.m02 * world2) / h;
-    var camera1 = (cmat.m10 * world0 + cmat.m11 * world1 + cmat.m12 * world2) / h;
-    //h = cpara[2 * 4 + 0] * world3 + cpara[2 * 4 + 1] * world4 + cpara[2 * 4 + 2] * world5;
-    h = cmat.m20 * world3 + cmat.m21 * world4 + cmat.m22 * world5;
-    if (h == 0.0) {
-      throw new NyARException();
-    }
-    //final double camera2 = (cpara[0 * 4 + 0] * world3 + cpara[0 * 4 + 1] * world4 + cpara[0 * 4 + 2] * world5) / h;
-    //final double camera3 = (cpara[1 * 4 + 0] * world3 + cpara[1 * 4 + 1] * world4 + cpara[1 * 4 + 2] * world5) / h;
-    var camera2 = (cmat.m00 * world3 + cmat.m01 * world4 + cmat.m02 * world5) / h;
-    var camera3 = (cmat.m10 * world3 + cmat.m11 * world4 + cmat.m12 * world5) / h;
-    var v = (i_end_vertex.x - i_start_vertex.x) * (camera2 - camera0) + (i_end_vertex.y - i_start_vertex.y) * (camera3 - camera1);
-    if (v < 0) {
-      this.v1 = -this.v1;
-      this.v2 = -this.v2;
-      this.v3 = -this.v3;
-    }
-  },
-  /**
-   * int check_rotation( double rot[2][3] )
-   * 2つのベクトル引数の調整をする？
-   * @param i_r
-   * @throws NyARException
-   */
-  checkRotation : function(io_vec1,io_vec2)
-  {
-    var w;
-    var f;
-    var vec10 = io_vec1.v1;
-    var vec11 = io_vec1.v2;
-    var vec12 = io_vec1.v3;
-    var vec20 = io_vec2.v1;
-    var vec21 = io_vec2.v2;
-    var vec22 = io_vec2.v3;
-    var vec30 = vec11 * vec22 - vec12 * vec21;
-    var vec31 = vec12 * vec20 - vec10 * vec22;
-    var vec32 = vec10 * vec21 - vec11 * vec20;
-    w = Math.sqrt(vec30 * vec30 + vec31 * vec31 + vec32 * vec32);
-    if (w == 0.0) {
-      throw new NyARException();
-    }
-    vec30 /= w;
-    vec31 /= w;
-    vec32 /= w;
-    var cb = vec10 * vec20 + vec11 * vec21 + vec12 * vec22;
-    if (cb < 0){
-      cb=-cb;//cb *= -1.0;
-    }
-    var ca = (Math.sqrt(cb + 1.0) + Math.sqrt(1.0 - cb)) * 0.5;
-    if (vec31 * vec10 - vec11 * vec30 != 0.0) {
-      f = 0;
-    } else {
-      if (vec32 * vec10 - vec12 * vec30 != 0.0) {
-        w = vec11;vec11 = vec12;vec12 = w;
-        w = vec31;vec31 = vec32;vec32 = w;
-        f = 1;
-      } else {
-        w = vec10;vec10 = vec12;vec12 = w;
-        w = vec30;vec30 = vec32;vec32 = w;
-        f = 2;
-      }
-    }
-    if (vec31 * vec10 - vec11 * vec30 == 0.0) {
-      throw new NyARException();
-    }
-    var k1,k2,k3,k4;
-    var a, b, c, d;
-    var p1, q1, r1;
-    var p2, q2, r2;
-    var p3, q3, r3;
-    var p4, q4, r4;
-    k1 = (vec11 * vec32 - vec31 * vec12) / (vec31 * vec10 - vec11 * vec30);
-    k2 = (vec31 * ca) / (vec31 * vec10 - vec11 * vec30);
-    k3 = (vec10 * vec32 - vec30 * vec12) / (vec30 * vec11 - vec10 * vec31);
-    k4 = (vec30 * ca) / (vec30 * vec11 - vec10 * vec31);
-    a = k1 * k1 + k3 * k3 + 1;
-    b = k1 * k2 + k3 * k4;
-    c = k2 * k2 + k4 * k4 - 1;
-    d = b * b - a * c;
-    if (d < 0) {
-      throw new NyARException();
-    }
-    r1 = (-b + Math.sqrt(d)) / a;
-    p1 = k1 * r1 + k2;
-    q1 = k3 * r1 + k4;
-    r2 = (-b - Math.sqrt(d)) / a;
-    p2 = k1 * r2 + k2;
-    q2 = k3 * r2 + k4;
-    if (f == 1) {
-      w = q1;q1 = r1;r1 = w;
-      w = q2;q2 = r2;r2 = w;
-      w = vec11;vec11 = vec12;vec12 = w;
-      w = vec31;vec31 = vec32;vec32 = w;
-      f = 0;
-    }
-    if (f == 2) {
-      w = p1;p1 = r1;r1 = w;
-      w = p2;p2 = r2;r2 = w;
-      w = vec10;vec10 = vec12;vec12 = w;
-      w = vec30;vec30 = vec32;vec32 = w;
-      f = 0;
-    }
-    if (vec31 * vec20 - vec21 * vec30 != 0.0) {
-      f = 0;
-    } else {
-      if (vec32 * vec20 - vec22 * vec30 != 0.0) {
-        w = vec21;vec21 = vec22;vec22 = w;
-        w = vec31;vec31 = vec32;vec32 = w;
-        f = 1;
-      } else {
-        w = vec20;vec20 = vec22;vec22 = w;
-        w = vec30;vec30 = vec32;vec32 = w;
-        f = 2;
-      }
-    }
-    if (vec31 * vec20 - vec21 * vec30 == 0.0) {
-      throw new NyARException();
-    }
-    k1 = (vec21 * vec32 - vec31 * vec22) / (vec31 * vec20 - vec21 * vec30);
-    k2 = (vec31 * ca) / (vec31 * vec20 - vec21 * vec30);
-    k3 = (vec20 * vec32 - vec30 * vec22) / (vec30 * vec21 - vec20 * vec31);
-    k4 = (vec30 * ca) / (vec30 * vec21 - vec20 * vec31);
-    a = k1 * k1 + k3 * k3 + 1;
-    b = k1 * k2 + k3 * k4;
-    c = k2 * k2 + k4 * k4 - 1;
-    d = b * b - a * c;
-    if (d < 0) {
-      throw new NyARException();
-    }
-    r3 = (-b + Math.sqrt(d)) / a;
-    p3 = k1 * r3 + k2;
-    q3 = k3 * r3 + k4;
-    r4 = (-b - Math.sqrt(d)) / a;
-    p4 = k1 * r4 + k2;
-    q4 = k3 * r4 + k4;
-    if (f == 1) {
-      w = q3;q3 = r3;r3 = w;
-      w = q4;q4 = r4;r4 = w;
-      w = vec21;vec21 = vec22;vec22 = w;
-      w = vec31;vec31 = vec32;vec32 = w;
-      f = 0;
-    }
-    if (f == 2) {
-      w = p3;p3 = r3;r3 = w;
-      w = p4;p4 = r4;r4 = w;
-      w = vec20;vec20 = vec22;vec22 = w;
-      w = vec30;vec30 = vec32;vec32 = w;
-      f = 0;
-    }
-    var e1 = p1 * p3 + q1 * q3 + r1 * r3;
-    if (e1 < 0) {
-      e1 = -e1;
-    }
-    var e2 = p1 * p4 + q1 * q4 + r1 * r4;
-    if (e2 < 0) {
-      e2 = -e2;
-    }
-    var e3 = p2 * p3 + q2 * q3 + r2 * r3;
-    if (e3 < 0) {
-      e3 = -e3;
-    }
-    var e4 = p2 * p4 + q2 * q4 + r2 * r4;
-    if (e4 < 0) {
-      e4 = -e4;
-    }
-    if (e1 < e2) {
-      if (e1 < e3) {
-        if (e1 < e4) {
-          io_vec1.v1 = p1;
-          io_vec1.v2 = q1;
-          io_vec1.v3 = r1;
-          io_vec2.v1 = p3;
-          io_vec2.v2 = q3;
-          io_vec2.v3 = r3;
-        } else {
-          io_vec1.v1 = p2;
-          io_vec1.v2 = q2;
-          io_vec1.v3 = r2;
-          io_vec2.v1 = p4;
-          io_vec2.v2 = q4;
-          io_vec2.v3 = r4;
-        }
-      } else {
-        if (e3 < e4) {
-          io_vec1.v1 = p2;
-          io_vec1.v2 = q2;
-          io_vec1.v3 = r2;
-          io_vec2.v1 = p3;
-          io_vec2.v2 = q3;
-          io_vec2.v3 = r3;
-        } else {
-          io_vec1.v1 = p2;
-          io_vec1.v2 = q2;
-          io_vec1.v3 = r2;
-          io_vec2.v1 = p4;
-          io_vec2.v2 = q4;
-          io_vec2.v3 = r4;
-        }
-      }
-    } else {
-      if (e2 < e3) {
-        if (e2 < e4) {
-          io_vec1.v1 = p1;
-          io_vec1.v2 = q1;
-          io_vec1.v3 = r1;
-          io_vec2.v1 = p4;
-          io_vec2.v2 = q4;
-          io_vec2.v3 = r4;
-        } else {
-          io_vec1.v1 = p2;
-          io_vec1.v2 = q2;
-          io_vec1.v3 = r2;
-          io_vec2.v1 = p4;
-          io_vec2.v2 = q4;
-          io_vec2.v3 = r4;
-        }
-      } else {
-        if (e3 < e4) {
-          io_vec1.v1 = p2;
-          io_vec1.v2 = q2;
-          io_vec1.v3 = r2;
-          io_vec2.v1 = p3;
-          io_vec2.v2 = q3;
-          io_vec2.v3 = r3;
-        } else {
-          io_vec1.v1 = p2;
-          io_vec1.v2 = q2;
-          io_vec1.v3 = r2;
-          io_vec2.v1 = p4;
-          io_vec2.v2 = q4;
-          io_vec2.v3 = r4;
-        }
-      }
-    }
-    return;
-  }
-})
-
-INyARTransportVectorSolver = ASKlass('INyARTransportVectorSolver',
-{
-  set2dVertex : function(i_ref_vertex_2d,i_number_of_vertex){},
-  /**
-   * 画面座標群と3次元座標群から、平行移動量を計算します。
-   * 2d座標系は、直前に実行したset2dVertexのものを使用します。
-   * @param i_vertex_2d
-   * 直前のset2dVertexコールで指定したものと同じものを指定してください。
-   * @param i_vertex3d
-   * 3次元空間の座標群を設定します。頂点の順番は、画面座標群と同じ順序で格納してください。
-   * @param o_transfer
-   * @throws NyARException
-   */
-  solveTransportVector : function(i_vertex3d, o_transfer){}
-})
-
-
-/**
- * 並進ベクトル[T]を３次元座標[b]と基点の回転済行列[M]から計算します。
- *
- * アルゴリズムは、ARToolKit 拡張現実プログラミング入門 の、P207のものです。
- *
- * 計算手順
- * [A]*[T]=bを、[A]T*[A]*[T]=[A]T*[b]にする。
- * set2dVertexで[A]T*[A]=[M]を計算して、Aの3列目の情報だけ保存しておく。
- * getTransportVectorで[M]*[T]=[A]T*[b]を連立方程式で解いて、[T]を得る。
- */
-NyARTransportVectorSolver = ASKlass('NyARTransportVectorSolver', INyARTransportVectorSolver,
-{
-  _cx : null,
-  _cy : null,
-  _projection_mat : null,
-  _nmber_of_vertex : 0,
-  NyARTransportVectorSolver : function(i_projection_mat_ref,i_max_vertex)
-  {
-    this._projection_mat=i_projection_mat_ref;
-    this._cx=new FloatVector(i_max_vertex);
-    this._cy=new FloatVector(i_max_vertex);
-    return;
-  },
-  _a00:0,_a01_10:0,_a02_20:0,_a11:0,_a12_21:0,_a22 : 0,
-  /**
-   * 画面上の座標群を指定します。
-   * @param i_ref_vertex_2d
-   * 歪み矯正済の画面上の頂点座標群への参照値を指定します。
-   * @throws NyARException
-   *
-   */
-  set2dVertex : function(i_ref_vertex_2d,i_number_of_vertex)
-  {
-    //3x2nと2n*3の行列から、最小二乗法計算するために3x3マトリクスを作る。
-    //行列[A]の3列目のキャッシュ
-    var cx=this._cx;
-    var cy=this._cy;
-    var m22;
-    var p00=this._projection_mat.m00;
-    var p01=this._projection_mat.m01;
-    var p11=this._projection_mat.m11;
-    var p12=this._projection_mat.m12;
-    var p02=this._projection_mat.m02;
-    var w1,w2,w3,w4;
-    this._a00=i_number_of_vertex*p00*p00;
-    this._a01_10=i_number_of_vertex*p00*p01;
-    this._a11=i_number_of_vertex*(p01*p01+p11*p11);
-    //[A]T*[A]の計算
-    m22=0;
-    w1=w2=0;
-    for(var i=0;i<i_number_of_vertex;i++){
-      //座標を保存しておく。
-      w3=p02-(cx[i]=i_ref_vertex_2d[i].x);
-      w4=p12-(cy[i]=i_ref_vertex_2d[i].y);
-      w1+=w3;
-      w2+=w4;
-      m22+=w3*w3+w4*w4;
-    }
-    this._a02_20=w1*p00;
-    this._a12_21=p01*w1+p11*w2;
-    this._a22=m22;
-    this._nmber_of_vertex=i_number_of_vertex;
-    return;
-  },
-  /**
-   * 画面座標群と3次元座標群から、平行移動量を計算します。
-   * 2d座標系は、直前に実行したset2dVertexのものを使用します。
-   * @param i_vertex_2d
-   * 直前のset2dVertexコールで指定したものと同じものを指定してください。
-   * @param i_vertex3d
-   * 3次元空間の座標群を設定します。頂点の順番は、画面座標群と同じ順序で格納してください。
-   * @param o_transfer
-   * @throws NyARException
-   */
-  solveTransportVector : function(i_vertex3d,o_transfer)
-  {
-    var number_of_vertex=this._nmber_of_vertex;
-    var p00=this._projection_mat.m00;
-    var p01=this._projection_mat.m01;
-    var p02=this._projection_mat.m02;
-    var p11=this._projection_mat.m11;
-    var p12=this._projection_mat.m12;
-    //行列[A]の3列目のキャッシュ
-    var cx=this._cx;
-    var cy=this._cy;
-    //回転行列を元座標の頂点群に適応
-    //[A]T*[b]を計算
-    var b1, b2, b3;
-    b1 = b2 = b3 = 0;
-    for(var i=0;i<number_of_vertex;i++)
-    {
-      var w1=i_vertex3d[i].z*cx[i]-p00*i_vertex3d[i].x-p01*i_vertex3d[i].y-p02*i_vertex3d[i].z;
-      var w2=i_vertex3d[i].z*cy[i]-p11*i_vertex3d[i].y-p12*i_vertex3d[i].z;
-      b1+=w1;
-      b2+=w2;
-      b3+=cx[i]*w1+cy[i]*w2;
-    }
-    //[A]T*[b]を計算
-    b3=p02*b1+p12*b2-b3;//順番変えたらダメよ
-    b2=p01*b1+p11*b2;
-    b1=p00*b1;
-    //([A]T*[A])*[T]=[A]T*[b]を方程式で解く。
-    //a01とa10を0と仮定しても良いんじゃないかな？
-    var a00=this._a00;
-    var a01=this._a01_10;
-    var a02=this._a02_20;
-    var a11=this._a11;
-    var a12=this._a12_21;
-    var a22=this._a22;
-    var t1=a22*b2-a12*b3;
-    var t2=a12*b2-a11*b3;
-    var t3=a01*b3-a02*b2;
-    var t4=a12*a12-a11*a22;
-    var t5=a02*a12-a01*a22;
-    var t6=a02*a11-a01*a12;
-    var det=a00*t4-a01*t5 + a02*t6;
-    o_transfer.x= (a01*t1 - a02*t2 +b1*t4)/det;
-    o_transfer.y=-(a00*t1 + a02*t3 +b1*t5)/det;
-    o_transfer.z= (a00*t2 + a01*t3 +b1*t6)/det;
-    return;
-  }
-})
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * PROJECT: FLARToolKit
- * --------------------------------------------------------------------------------
- * This work is based on the NyARToolKit developed by
- *   R.Iizuka (nyatla)
- * http://nyatla.jp/nyatoolkit/
- *
- * The FLARToolKit is ActionScript 3.0 version ARToolkit class library.
- * Copyright (C)2008 Saqoosha
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  http://www.libspark.org/wiki/saqoosha/FLARToolKit
- *  <saq(at)saqoosha.net>
- *
- */
-FLARTransMatResult = NyARTransMatResult;
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * JSARToolkit
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- *   Hirokazu Kato
- *   Mark Billinghurst
- *   HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * And the NyARToolkitAS3 ARToolKit class library.
- *   Copyright (C)2010 Ryo Iizuka
- *
- * JSARToolkit is a JavaScript port of NyARToolkitAS3.
- *   Copyright (C)2010 Ilmari Heikkinen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  ilmari.heikkinen@gmail.com
- *
- */
-
-
-NyARMath = Klass(
-{
-  /**
-   * p2-p1ベクトルのsquare normを計算する。
-   * @param i_p1
-   * @param i_p2
-   * @return
-   */
-  sqNorm_NyARDoublePoint2d : function(i_p1,i_p2 )
-  {
-    var x,y;
-    x=i_p2.x-i_p1.x;
-    y=i_p2.y-i_p1.y;
-    return x*x+y*y;
-  },
-  sqNorm_Number : function(i_p1x,i_p1y,i_p2x,i_p2y)
-  {
-    var x,y;
-    x=i_p2x-i_p1x;
-    y=i_p2y-i_p1y;
-    return x*x+y*y;
-  },
-  /**
-   * p2-p1ベクトルのsquare normを計算する。
-   * @param i_p1
-   * @param i_p2
-   * @return
-   */
-  sqNorm_NyARDoublePoint3d : function(i_p1,i_p2)
-  {
-    var x, y, z;
-    x=i_p2.x-i_p1.x;
-    y=i_p2.y-i_p1.y;
-    z=i_p2.z-i_p1.z;
-    return x*x+y*y+z*z;
-  },
-  /**
-   * 3乗根を求められないシステムで、３乗根を求めます。
-   * http://aoki2.si.gunma-u.ac.jp/JavaScript/src/3jisiki.html
-   * @param i_in
-   * @return
-   */
-  cubeRoot : function(i_in)
-  {
-    var res = Math.pow(Math.abs(i_in), 1.0 / 3.0);
-    return (i_in >= 0) ? res : -res;
-  }
-})
-
-
-NyAREquationSolver = Klass(
-{
-  solve2Equation_3 : function(i_a, i_b,i_c,o_result)
-  {
-    NyAS3Utils.assert(i_a!=0);
-    return this.solve2Equation_2b(i_b/i_a,i_c/i_a,o_result,0);
-  },
-  solve2Equation_2a : function(i_b, i_c,o_result)
-  {
-    return this.solve2Equation_2b(i_b,i_c,o_result,0);
-  },
-  solve2Equation_2b : function(i_b, i_c,o_result,i_result_st)
-  {
-    var t=i_b*i_b-4*i_c;
-    if(t<0){
-      //虚数根
-      return 0;
-    }
-    if(t==0){
-      //重根
-      o_result[i_result_st+0]=-i_b/(2);
-      return 1;
-    }
-    //実根２個
-    t=Math.sqrt(t);
-    o_result[i_result_st+0]=(-i_b+t)/(2);
-    o_result[i_result_st+1]=(-i_b-t)/(2);
-    return 2;
-  },
-  /**
-   * ３次方程式 a*x^3+b*x^2+c*x+d=0の実根を求める。
-   * http://aoki2.si.gunma-u.ac.jp/JavaScript/src/3jisiki.html
-   * のコードを基にしてます。
-   * @param i_a
-   * X^3の係数
-   * @param i_b
-   * X^2の係数
-   * @param i_c
-   * X^1の係数
-   * @param i_d
-   * X^0の係数
-   * @param o_result
-   * 実根。double[3]を指定すること。
-   * @return
-   */
-  solve3Equation_4 : function(i_a, i_b, i_c, i_d,o_result)
-  {
-    NyAS3Utils.assert (i_a != 0);
-    return this.solve3Equation_3(i_b/i_a,i_c/i_a,i_d/i_a,o_result);
-  },
-  /**
-   * ３次方程式 x^3+b*x^2+c*x+d=0の実根を求める。
-   * だけを求める。
-   * http://aoki2.si.gunma-u.ac.jp/JavaScript/src/3jisiki.html
-   * のコードを基にしてます。
-   * @param i_b
-   * X^2の係数
-   * @param i_c
-   * X^1の係数
-   * @param i_d
-   * X^0の係数
-   * @param o_result
-   * 実根。double[1]以上を指定すること。
-   * @return
-   */
-  solve3Equation_3 : function(i_b,i_c,i_d,o_result)
-  {
-    var tmp,b,   p, q;
-    b = i_b/(3);
-    p = b * b - i_c / 3;
-    q = (b * (i_c - 2 * b * b) - i_d) / 2;
-    if ((tmp = q * q - p * p * p) == 0) {
-      // 重根
-      q = NyARMath.cubeRoot(q);
-      o_result[0] = 2 * q - b;
-      o_result[1] = -q - b;
-      return 2;
-    } else if (tmp > 0) {
-      // 実根1,虚根2
-      var a3 = NyARMath.cubeRoot(q + ((q > 0) ? 1 : -1) * Math.sqrt(tmp));
-      var b3 = p / a3;
-      o_result[0] = a3 + b3 - b;
-      // 虚根:-0.5*(a3+b3)-b,Math.abs(a3-b3)*Math.sqrt(3.0)/2
-      return 1;
-    } else {
-      // 実根3
-      tmp = 2 * Math.sqrt(p);
-      var t = Math.acos(q / (p * tmp / 2));
-      o_result[0] = tmp * Math.cos(t / 3) - b;
-      o_result[1] = tmp * Math.cos((t + 2 * Math.PI) / 3) - b;
-      o_result[2] = tmp * Math.cos((t + 4 * Math.PI) / 3) - b;
-      return 3;
-    }
-  },
-  /**
-   * ４次方程式の実根だけを求める。
-   * @param i_a
-   * X^3の係数
-   * @param i_b
-   * X^2の係数
-   * @param i_c
-   * X^1の係数
-   * @param i_d
-   * X^0の係数
-   * @param o_result
-   * 実根。double[3]を指定すること。
-   * @return
-   */
-  solve4Equation : function(i_a, i_b, i_c, i_d,i_e,o_result)
-  {
-    NyAS3Utils.assert (i_a != 0);
-    var A3,A2,A1,A0,B3;
-    A3=i_b/i_a;
-    A2=i_c/i_a;
-    A1=i_d/i_a;
-    A0=i_e/i_a;
-    B3=A3/4;
-    var p,q,r;
-    var B3_2=B3*B3;
-    p=A2-6*B3_2;//A2-6*B3*B3;
-    q=A1+B3*(-2*A2+8*B3_2);//A1-2*A2*B3+8*B3*B3*B3;
-    r=A0+B3*(-A1+A2*B3)-3*B3_2*B3_2;//A0-A1*B3+A2*B3*B3-3*B3*B3*B3*B3;
-    if(q==0){
-      var result_0,result_1;
-      //複二次式
-      var res=this.solve2Equation_2b(p,r,o_result,0);
-      switch(res){
-      case 0:
-        //全て虚数解
-        return 0;
-      case 1:
-        //重根
-        //解は0,1,2の何れか。
-        result_0=o_result[0];
-        if(result_0<0){
-          //全て虚数解
-          return 0;
-        }
-        //実根1個
-        if(result_0==0){
-          //NC
-          o_result[0]=0-B3;
-          return 1;
-        }
-        //実根2個
-        result_0=Math.sqrt(result_0);
-        o_result[0]=result_0-B3;
-        o_result[1]=-result_0-B3;
-        return 2;
-      case 2:
-        //実根２個だからt==t2==0はありえない。(case1)
-        //解は、0,2,4の何れか。
-        result_0=o_result[0];
-        result_1=o_result[1];
-        var number_of_result=0;
-        if(result_0>0){
-          //NC
-          result_0=Math.sqrt(result_0);
-          o_result[0]= result_0-B3;
-          o_result[1]=-result_0-B3;
-          number_of_result+=2;
-        }
-        if(result_1>0)
-        {
-          //NC
-          result_1=Math.sqrt(result_1);
-          o_result[number_of_result+0]= result_1-B3;
-          o_result[number_of_result+1]=-result_1-B3;
-          number_of_result+=2;
-        }
-        return number_of_result;
-      default:
-        throw new NyARException();
-      }
-    }else{
-      //それ以外
-      //最適化ポイント:
-      //u^3  + (2*p)*u^2  +((- 4*r)+(p^2))*u -q^2= 0
-      var u=this.solve3Equation_1((2*p),(- 4*r)+(p*p),-q*q);
-      if(u<0){
-        //全て虚数解
-        return 0;
-      }
-      var ru=Math.sqrt(u);
-      //2次方程式を解いてyを計算(最適化ポイント)
-      var result_1st,result_2nd;
-      result_1st=this.solve2Equation_2b(-ru,(p+u)/2+ru*q/(2*u),o_result,0);
-      //配列使い回しのために、変数に退避
-      switch(result_1st){
-      case 0:
-        break;
-      case 1:
-        o_result[0]=o_result[0]-B3;
-        break;
-      case 2:
-        o_result[0]=o_result[0]-B3;
-        o_result[1]=o_result[1]-B3;
-        break;
-      default:
-        throw new NyARException();
-      }
-      result_2nd=this.solve2Equation_2b(ru,(p+u)/2-ru*q/(2*u),o_result,result_1st);
-      //0,1番目に格納
-      switch(result_2nd){
-      case 0:
-        break;
-      case 1:
-        o_result[result_1st+0]=o_result[result_1st+0]-B3;
-        break;
-      case 2:
-        o_result[result_1st+0]=o_result[result_1st+0]-B3;
-        o_result[result_1st+1]=o_result[result_1st+1]-B3;
-        break;
-      default:
-        throw new NyARException();
-      }
-      return result_1st+result_2nd;
-    }
-  },
-  /**
-   * 3次方程式の実根を１個だけ求める。
-   * 4字方程式で使う。
-   * @param i_b
-   * @param i_c
-   * @param i_d
-   * @param o_result
-   * @return
-   */
-  solve3Equation_1 : function(i_b,i_c, i_d)
-  {
-    var tmp,b,   p, q;
-    b = i_b/(3);
-    p = b * b - i_c / 3;
-    q = (b * (i_c - 2 * b * b) - i_d) / 2;
-    if ((tmp = q * q - p * p * p) == 0) {
-      // 重根
-      q = NyARMath.cubeRoot(q);
-      return 2 * q - b;
-    } else if (tmp > 0) {
-      // 実根1,虚根2
-      var a3 = NyARMath.cubeRoot(q + ((q > 0) ? 1 : -1) * Math.sqrt(tmp));
-      var b3 = p / a3;
-      return a3 + b3 - b;
-    } else {
-      // 実根3
-      tmp = 2 * Math.sqrt(p);
-      var t = Math.acos(q / (p * tmp / 2));
-      return tmp * Math.cos(t / 3) - b;
-    }
-  }
-})
-
-NyARPerspectiveParamGenerator_O1 = Klass(
-{
-  _local_x : 0,
-  _local_y : 0,
-  _width : 0,
-  _height : 0,
-  initialize : function(i_local_x,i_local_y,i_width,i_height)
-  {
-    this._height=i_height;
-    this._width=i_width;
-    this._local_x=i_local_x;
-    this._local_y=i_local_y;
-    return;
-  },
-  getParam : function(i_vertex,o_param)
-  {
-    var ltx = this._local_x;
-    var lty = this._local_y;
-    var rbx = ltx + this._width;
-    var rby = lty + this._height;
-    var det_1;
-    var a13, a14, a23, a24, a33, a34, a43, a44;
-    var b11, b12, b13, b14, b21, b22, b23, b24, b31, b32, b33, b34, b41, b42, b43, b44;
-    var t1, t2, t3, t4, t5, t6;
-    var v1, v2, v3, v4;
-    var kx0, kx1, kx2, kx3, kx4, kx5, kx6, kx7;
-    var ky0, ky1, ky2, ky3, ky4, ky5, ky6, ky7;
-    {
-      v1 = i_vertex[0].x;
-      v2 = i_vertex[1].x;
-      v3 = i_vertex[2].x;
-      v4 = i_vertex[3].x;
-      a13 = -ltx * v1;
-      a14 = -lty * v1;
-      a23 = -rbx * v2;
-      a24 = -lty * v2;
-      a33 = -rbx * v3;
-      a34 = -rby * v3;
-      a43 = -ltx * v4;
-      a44 = -rby * v4;
-      t1 = a33 * a44 - a34 * a43;
-      t4 = a34 * ltx - rbx * a44;
-      t5 = rbx * a43 - a33 * ltx;
-      t2 = rby * (a34 - a44);
-      t3 = rby * (a43 - a33);
-      t6 = rby * (rbx - ltx);
-      b21 = -a23 * t4 - a24 * t5 - rbx * t1;
-      b11 = (a23 * t2 + a24 * t3) + lty * t1;
-      b31 = (a24 * t6 - rbx * t2) + lty * t4;
-      b41 = (-rbx * t3 - a23 * t6) + lty * t5;
-      t1 = a43 * a14 - a44 * a13;
-      t2 = a44 * lty - rby * a14;
-      t3 = rby * a13 - a43 * lty;
-      t4 = ltx * (a44 - a14);
-      t5 = ltx * (a13 - a43);
-      t6 = ltx * (lty - rby);
-      b12 = -rby * t1 - a33 * t2 - a34 * t3;
-      b22 = (a33 * t4 + a34 * t5) + rbx * t1;
-      b32 = (-a34 * t6 - rby * t4) + rbx * t2;
-      b42 = (-rby * t5 + a33 * t6) + rbx * t3;
-      t1 = a13 * a24 - a14 * a23;
-      t4 = a14 * rbx - ltx * a24;
-      t5 = ltx * a23 - a13 * rbx;
-      t2 = lty * (a14 - a24);
-      t3 = lty * (a23 - a13);
-      t6 = lty * (ltx - rbx);
-      b23 = -a43 * t4 - a44 * t5 - ltx * t1;
-      b13 = (a43 * t2 + a44 * t3) + rby * t1;
-      b33 = (a44 * t6 - ltx * t2) + rby * t4;
-      b43 = (-ltx * t3 - a43 * t6) + rby * t5;
-      t1 = a23 * a34 - a24 * a33;
-      t2 = a24 * rby - lty * a34;
-      t3 = lty * a33 - a23 * rby;
-      t4 = rbx * (a24 - a34);
-      t5 = rbx * (a33 - a23);
-      t6 = rbx * (rby - lty);
-      b14 = -lty * t1 - a13 * t2 - a14 * t3;
-      b24 = a13 * t4 + a14 * t5 + ltx * t1;
-      b34 = -a14 * t6 - lty * t4 + ltx * t2;
-      b44 = -lty * t5 + a13 * t6 + ltx * t3;
-      det_1 = (ltx * (b11 + b14) + rbx * (b12 + b13));
-      if (det_1 == 0) {
-        det_1=0.0001;
-        //System.out.println("Could not get inverse matrix(1).");
-        //return false;
-      }
-      det_1 = 1 / det_1;
-      kx0 = (b11 * v1 + b12 * v2 + b13 * v3 + b14 * v4) * det_1;
-      kx1 = (b11 + b12 + b13 + b14) * det_1;
-      kx2 = (b21 * v1 + b22 * v2 + b23 * v3 + b24 * v4) * det_1;
-      kx3 = (b21 + b22 + b23 + b24) * det_1;
-      kx4 = (b31 * v1 + b32 * v2 + b33 * v3 + b34 * v4) * det_1;
-      kx5 = (b31 + b32 + b33 + b34) * det_1;
-      kx6 = (b41 * v1 + b42 * v2 + b43 * v3 + b44 * v4) * det_1;
-      kx7 = (b41 + b42 + b43 + b44) * det_1;
-    }
-    {
-      v1 = i_vertex[0].y;
-      v2 = i_vertex[1].y;
-      v3 = i_vertex[2].y;
-      v4 = i_vertex[3].y;
-      a13 = -ltx * v1;
-      a14 = -lty * v1;
-      a23 = -rbx * v2;
-      a24 = -lty * v2;
-      a33 = -rbx * v3;
-      a34 = -rby * v3;
-      a43 = -ltx * v4;
-      a44 = -rby * v4;
-      t1 = a33 * a44 - a34 * a43;
-      t4 = a34 * ltx - rbx * a44;
-      t5 = rbx * a43 - a33 * ltx;
-      t2 = rby * (a34 - a44);
-      t3 = rby * (a43 - a33);
-      t6 = rby * (rbx - ltx);
-      b21 = -a23 * t4 - a24 * t5 - rbx * t1;
-      b11 = (a23 * t2 + a24 * t3) + lty * t1;
-      b31 = (a24 * t6 - rbx * t2) + lty * t4;
-      b41 = (-rbx * t3 - a23 * t6) + lty * t5;
-      t1 = a43 * a14 - a44 * a13;
-      t2 = a44 * lty - rby * a14;
-      t3 = rby * a13 - a43 * lty;
-      t4 = ltx * (a44 - a14);
-      t5 = ltx * (a13 - a43);
-      t6 = ltx * (lty - rby);
-      b12 = -rby * t1 - a33 * t2 - a34 * t3;
-      b22 = (a33 * t4 + a34 * t5) + rbx * t1;
-      b32 = (-a34 * t6 - rby * t4) + rbx * t2;
-      b42 = (-rby * t5 + a33 * t6) + rbx * t3;
-      t1 = a13 * a24 - a14 * a23;
-      t4 = a14 * rbx - ltx * a24;
-      t5 = ltx * a23 - a13 * rbx;
-      t2 = lty * (a14 - a24);
-      t3 = lty * (a23 - a13);
-      t6 = lty * (ltx - rbx);
-      b23 = -a43 * t4 - a44 * t5 - ltx * t1;
-      b13 = (a43 * t2 + a44 * t3) + rby * t1;
-      b33 = (a44 * t6 - ltx * t2) + rby * t4;
-      b43 = (-ltx * t3 - a43 * t6) + rby * t5;
-      t1 = a23 * a34 - a24 * a33;
-      t2 = a24 * rby - lty * a34;
-      t3 = lty * a33 - a23 * rby;
-      t4 = rbx * (a24 - a34);
-      t5 = rbx * (a33 - a23);
-      t6 = rbx * (rby - lty);
-      b14 = -lty * t1 - a13 * t2 - a14 * t3;
-      b24 = a13 * t4 + a14 * t5 + ltx * t1;
-      b34 = -a14 * t6 - lty * t4 + ltx * t2;
-      b44 = -lty * t5 + a13 * t6 + ltx * t3;
-      det_1 = (ltx * (b11 + b14) + rbx * (b12 + b13));
-      if (det_1 == 0) {
-        det_1=0.0001;
-        //System.out.println("Could not get inverse matrix(2).");
-        //return false;
-      }
-      det_1 = 1 / det_1;
-      ky0 = (b11 * v1 + b12 * v2 + b13 * v3 + b14 * v4) * det_1;
-      ky1 = (b11 + b12 + b13 + b14) * det_1;
-      ky2 = (b21 * v1 + b22 * v2 + b23 * v3 + b24 * v4) * det_1;
-      ky3 = (b21 + b22 + b23 + b24) * det_1;
-      ky4 = (b31 * v1 + b32 * v2 + b33 * v3 + b34 * v4) * det_1;
-      ky5 = (b31 + b32 + b33 + b34) * det_1;
-      ky6 = (b41 * v1 + b42 * v2 + b43 * v3 + b44 * v4) * det_1;
-      ky7 = (b41 + b42 + b43 + b44) * det_1;
-    }
-    det_1 = kx5 * (-ky7) - (-ky5) * kx7;
-    if (det_1 == 0) {
-      det_1=0.0001;
-      //System.out.println("Could not get inverse matrix(3).");
-      //return false;
-    }
-    det_1 = 1 / det_1;
-    var C, F;
-    o_param[2] = C = (-ky7 * det_1) * (kx4 - ky4) + (ky5 * det_1) * (kx6 - ky6); // C
-    o_param[5] = F = (-kx7 * det_1) * (kx4 - ky4) + (kx5 * det_1) * (kx6 - ky6); // F
-    o_param[6] = kx4 - C * kx5;
-    o_param[7] = kx6 - C * kx7;
-    o_param[0] = kx0 - C * kx1;
-    o_param[1] = kx2 - C * kx3;
-    o_param[3] = ky0 - F * ky1;
-    o_param[4] = ky2 - F * ky3;
-    return true;
-  }
-})
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * JSARToolkit
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- *   Hirokazu Kato
- *   Mark Billinghurst
- *   HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * And the NyARToolkitAS3 ARToolKit class library.
- *   Copyright (C)2010 Ryo Iizuka
- *
- * JSARToolkit is a JavaScript port of NyARToolkitAS3.
- *   Copyright (C)2010 Ilmari Heikkinen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  ilmari.heikkinen@gmail.com
- *
- */
-NyIdMarkerParam = ASKlass('NyIdMarkerParam',
-{
-  /**
-   * マーカの方位値です。
-   */
-  direction : 0,
-  /**
-   * マーカ周辺のパターン閾値です。
-   */
-  threshold : 0
-})
-NyIdMarkerPattern = ASKlass('NyIdMarkerPattern',
-{
-  model : 0,
-  ctrl_domain : 0,
-  ctrl_mask : 0,
-  check : 0,
-  data : new IntVector(32)
-})
-
-
-
-
-TThreshold = ASKlass('TThreshold',
-{
-  th_h : 0,
-  th_l : 0,
-  th : 0,
-  lt_x : 0,
-  lt_y : 0,
-  rb_x : 0,
-  rb_y : 0
-})
-THighAndLow = ASKlass('THighAndLow',
-{
-  h : 0,
-  l : 0
-})
-/**
- * Marker pattern encoder。
- *
- */
-_bit_table_3 = new IntVector([
-  25,  26,  27,  28,  29,  30,  31,
-  48,  9,  10,  11,  12,  13,  32,
-  47,  24,  1,  2,  3,  14,  33,
-  46,  23,  8,  0,  4,  15,  34,
-  45,  22,  7,  6,  5,  16,  35,
-  44,  21,  20,  19,  18,  17,  36,
-  43,  42,  41,  40,  39,  38,  37
-  ])
-_bit_table_2 = new IntVector([
-  9,  10,  11,  12,  13,
-  24,  1,  2,  3,  14,
-  23,  8,  0,  4,  15,
-  22,  7,  6,  5,  16,
-  21,  20,  19,  18,  17])
-MarkerPattEncoder = ASKlass('MarkerPattEncoder',
-{
-  _bit_table_2 : _bit_table_2,
-  _bit_table_3 : _bit_table_3,
-  _bit_tables : [
-    _bit_table_2,_bit_table_3,null,null,null,null,null],
-  /**
-  * RECT(0):[0]=(0)
-  * RECT(1):[1]=(1-8)
-  * RECT(2):[2]=(9-16),[3]=(17-24)
-  * RECT(3):[4]=(25-32),[5]=(33-40),[6]=(41-48)
-  */
-  _bit_table : null,
-  _bits : new IntVector(16),
-  _work : new IntVector(16),
-  _model : 0,
-  setBitByBitIndex : function(i_index_no,i_value)
-  {
-    NyAS3Utils.assert(i_value==0 || i_value==1);
-    var bit_no=this._bit_table[i_index_no];
-    if(bit_no==0){
-      this._bits[0]=i_value;
-    }else{
-      var bidx=toInt((bit_no-1)/8)+1;
-      var sidx=(bit_no-1)%8;
-      this._bits[bidx]=(this._bits[bidx]&(~(0x01<<sidx)))|(i_value<<sidx);
-    }
-    return;
-  }
-  ,setBit : function(i_bit_no,i_value)
-  {
-    NyAS3Utils.assert(i_value==0 || i_value==1);
-    if(i_bit_no==0){
-      this._bits[0]=i_value;
-    }else{
-      var bidx=toInt((i_bit_no-1)/8)+1;
-      var sidx=(i_bit_no-1)%8;
-      this._bits[bidx]=(this._bits[bidx]&(~(0x01<<sidx)))|(i_value<<sidx);
-    }
-    return;
-  }
-  ,getBit : function(i_bit_no)
-  {
-    if(i_bit_no==0){
-      return this._bits[0];
-    }else{
-      var bidx=toInt((i_bit_no-1)/8)+1;
-      var sidx=(i_bit_no-1)%8;
-      return (this._bits[bidx]>>(sidx))&(0x01);
-    }
-  }
-  ,getModel : function()
-  {
-    return this._model;
-  }
-  ,getControlValue : function(i_model,i_data)
-  {
-    var v;
-    switch(i_model){
-    case 2:
-      v=(i_data[2] & 0x0e)>>1;
-      return v>=5?v-1:v;
-    case 3:
-      v=(i_data[4] & 0x3e)>>1;
-      return v>=21?v-1:v;
-    case 4:
-    case 5:
-    case 6:
-        case 7:
-        default:
-            break;
-    }
-    return -1;
-  }
-  ,getCheckValue : function(i_model,i_data)
-  {
-    var v;
-    switch(i_model){
-    case 2:
-      v=(i_data[2] & 0xe0)>>5;
-      return v>5?v-1:v;
-    case 3:
-      v=((i_data[4] & 0x80)>>7) |((i_data[5] & 0x0f)<<1);
-      return v>21?v-1:v;
-    case 4:
-    case 5:
-    case 6:
-        case 7:
-        default:
-            break;
-    }
-    return -1;
-  }
-  ,initEncoder : function(i_model)
-  {
-    if(i_model>3 || i_model<2){
-      //Lv4以降に対応する時は、この制限を変える。
-      // Change this when Lv4 is supported.
-      return false;
-    }
-    this._bit_table=this._bit_tables[i_model-2];
-    this._model=i_model;
-    return true;
-  }
-  ,getDirection : function()
-  {
-    var l,t,r,b;
-    var timing_pat;
-    switch(this._model){
-    case 2:
-      //トラッキングセルを得る
-      // get tracking cel
-      t=this._bits[2] & 0x1f;
-      r=((this._bits[2] & 0xf0)>>4)|((this._bits[3]&0x01)<<4);
-      b=this._bits[3] & 0x1f;
-      l=((this._bits[3] & 0xf0)>>4)|((this._bits[2]&0x01)<<4);
-      timing_pat=0x0a;
-      break;
-    case 3:
-      t=this._bits[4] & 0x7f;
-      r=((this._bits[4] & 0xc0)>>6)|((this._bits[5] & 0x1f)<<2);
-      b=((this._bits[5] & 0xf0)>>4)|((this._bits[6] & 0x07)<<4);
-      l=((this._bits[6] & 0xfc)>>2)|((this._bits[4] & 0x01)<<6);
-      timing_pat=0x2a;
-      break;
-    default:
-      return -3;
-    }
-    //タイミングパターンの比較
-    // timing pattern comparison
-    if(t==timing_pat){
-      if(r==timing_pat){
-        return (b!=timing_pat && l!=timing_pat)?2:-2;
-      }else if(l==timing_pat){
-        return (b!=timing_pat && r!=timing_pat)?3:-2;
-      }
-    }else if(b==timing_pat){
-      if(r==timing_pat){
-        return (t!=timing_pat && l!=timing_pat)?1:-2;
-      }else if(l==timing_pat){
-        return (t!=timing_pat && r!=timing_pat)?0:-2;
-      }
-    }
-    return -1;
-  }
-  /**
-  * 格納しているマーカパターンをエンコードして、マーカデータを返します。
-  * Encodes the stored marker pattern, writes marker data to o_out.
-  * @param o_out
-  * @return
-  * 成功すればマーカの方位を返却します。失敗すると-1を返します。
-  * On success, returns the marker direction. On failure, returns -1.
-  */
-  ,encode : function(o_out)
-  {
-    var d=this.getDirection();
-    if(d<0){
-      return -1;
-    }
-    //回転ビットの取得
-    // Acquire the rotation bit
-    this.getRotatedBits(d,o_out.data);
-    var model=this._model;
-    //周辺ビットの取得
-    // Acquire border bits
-    o_out.model=model;
-    var control_bits=this.getControlValue(model,o_out.data);
-    o_out.check=this.getCheckValue(model,o_out.data);
-    o_out.ctrl_mask=control_bits%5;
-    o_out.ctrl_domain=toInt(control_bits/5);
-    if(o_out.ctrl_domain!=0 || o_out.ctrl_mask!=0){
-      // failed to find a proper mask and domain, return -1
-      return -1;//ドメイン、マスクは現在0のみなので、それ以外の場合-1（失敗）を返す
-    }
-    //マスク解除処理を実装すること
-    // implement mask release
-    return d;
-  }
-  ,getRotatedBits : function(i_direction,o_out)
-  {
-    var sl=i_direction*2;
-    var sr=8-sl;
-    var w1;
-    o_out[0]=this._bits[0];
-    //RECT1
-    w1=this._bits[1];
-    o_out[1]=((w1<<sl)|(w1>>sr))& 0xff;
-    //RECT2
-    sl=i_direction*4;
-    sr=16-sl;
-    w1=this._bits[2]|(this._bits[3]<<8);
-    w1=(w1<<sl)|(w1>>sr);
-    o_out[2]=w1 & 0xff;
-    o_out[3]=(w1>>8) & 0xff;
-    if(this._model<2){
-      return;
-    }
-    //RECT3
-    sl=i_direction*6;
-    sr=24-sl;
-    w1=this._bits[4]|(this._bits[5]<<8)|(this._bits[6]<<16);
-    w1=(w1<<sl)|(w1>>sr);
-    o_out[4]=w1 & 0xff;
-    o_out[5]=(w1>>8) & 0xff;
-    o_out[6]=(w1>>16) & 0xff;
-    if(this._model<3){
-      return;
-    }
-    //RECT4(Lv4以降はここの制限を変える) uncomment when Lv4 supported
-  //    shiftLeft(this._bits,7,3,i_direction*8);
-  //    if(this._model<4){
-  //      return;
-  //    }
-    return;
-  }
-  ,shiftLeft : function(i_pack,i_start,i_length,i_ls)
-  {
-    var i;
-    var work=this._work;
-    //端数シフト
-    var mod_shift=i_ls%8;
-    for(i=i_length-1;i>=1;i--){
-      work[i]=(i_pack[i+i_start]<<mod_shift)|(0xff&(i_pack[i+i_start-1]>>(8-mod_shift)));
-    }
-    work[0]=(i_pack[i_start]<<mod_shift)|(0xff&(i_pack[i_start+i_length-1]>>(8-mod_shift)));
-    //バイトシフト
-    var byte_shift=toInt(i_ls/8)%i_length;
-    for(i=i_length-1;i>=0;i--){
-      i_pack[(byte_shift+i)%i_length+i_start]=0xff & work[i];
-    }
-    return;
-  }
-})
-INyIdMarkerData = ASKlass('INyIdMarkerData',
-{
-  /**
-   * i_targetのマーカデータと自身のデータが等しいかを返します。
-   * @param i_target
-   * 比較するマーカオブジェクト
-   * @return
-   * 等しいかの真偽値
-   */
-  isEqual : function(i_target){},
-  /**
-   * i_sourceからマーカデータをコピーします。
-   * @param i_source
-   */
-  copyFrom : function(i_source){}
-})
-
-
-/**
- * ラスタ画像の任意矩形から、NyARIdMarkerDataを抽出します。
- *
- */
-NyIdMarkerPickup = ASKlass('NyIdMarkerPickup',
-{
-  _perspective_reader : null,
-  __pickFromRaster_th : new TThreshold(),
-  __pickFromRaster_encoder : new MarkerPattEncoder(),
-  NyIdMarkerPickup : function()
-  {
-    this._perspective_reader=new PerspectivePixelReader();
-    return;
-  }
-  /**
-   * Initialize the marker pickup for a new frame.
-   * Clears out old values from perspective reader motion cache.
-   */
-  ,init : function()
-  {
-    this._perspective_reader.newFrame();
-  }
-  /**
-   * i_imageから、idマーカを読みだします。
-   * o_dataにはマーカデータ、o_paramにはまーかのパラメータを返却します。
-   * @param image
-   * @param i_square
-   * @param o_data
-   * @param o_param
-   * @return
-   * @throws NyARException
-   */
-  ,pickFromRaster : function(image,i_vertex,o_data,o_param)
-  {
-    //遠近法のパラメータを計算
-    if(!this._perspective_reader.setSourceSquare(i_vertex)){
-      if (window.DEBUG)
-        console.log('NyIdMarkerPickup.pickFromRaster: could not setSourceSquare')
-      return false;
-    };
-    var reader=image.getGrayPixelReader();
-    var raster_size=image.getSize();
-    var th=this.__pickFromRaster_th;
-    var encoder=this.__pickFromRaster_encoder;
-    //マーカパラメータを取得
-    this._perspective_reader.detectThresholdValue(reader,raster_size,th);
-    if(!this._perspective_reader.readDataBits(reader,raster_size,th, encoder)){
-      if (window.DEBUG)
-        console.log('NyIdMarkerPickup.pickFromRaster: could not readDataBits')
-      return false;
-    }
-    var d=encoder.encode(o_data);
-    if(d<0){
-      if (window.DEBUG)
-        console.log('NyIdMarkerPickup.pickFromRaster: could not encode')
-      return false;
-    }
-    o_param.direction=d;
-    o_param.threshold=th.th;
-    return true;
-  }
-})
-
-
-
-
-
-
-/**
- * NyARColorPatt_NyIdMarkerがラスタからPerspective変換して読みだすためのクラス
- *
- */
-PerspectivePixelReader = ASKlass('PerspectivePixelReader',
-{
-  _param_gen : new NyARPerspectiveParamGenerator_O1(1,1,100,100),
-  _cparam : new FloatVector(8),
-  PerspectivePixelReader : function()
-  {
-    return;
-  }
-  ,maxPreviousFrameAge : 1
-  ,newFrame : function()
-  {
-    for (var i in this.previousFrames) {
-      var pf = this.previousFrames[i];
-      pf.age++;
-      if (pf.age > this.maxPreviousFrameAge) {
-        delete this.previousFrames[i];
-      }
-    }
-  }
-  ,setSourceSquare : function(i_vertex)
-  {
-    var cx = 0, cy = 0;
-    for (var i=0; i<4; i++) {
-      cx += i_vertex[i].x;
-      cy += i_vertex[i].y;
-    }
-    cx /= 4;
-    cy /= 4;
-    var qx = toInt(cx / 10);
-    var qy = toInt(cy / 10);
-    this.centerPoint[0] = qx;
-    this.centerPoint[1] = qy;
-    return this._param_gen.getParam(i_vertex, this._cparam);
-  }
-  /**
-  * 矩形からピクセルを切り出します
-  * @param i_lt_x
-  * @param i_lt_y
-  * @param i_step_x
-  * @param i_step_y
-  * @param i_width
-  * @param i_height
-  * @param i_out_st
-  * o_pixelへの格納場所の先頭インデクス
-  * @param o_pixel
-  * @throws NyARException
-  */
-  ,rectPixels : function(i_reader,i_raster_size,i_lt_x,i_lt_y,i_step_x,i_step_y,i_width,i_height,i_out_st,o_pixel)
-  {
-    var cpara=this._cparam;
-    var ref_x=this._ref_x;
-    var ref_y=this._ref_y;
-    var pixcel_temp=this._pixcel_temp;
-    var raster_width=i_raster_size.w;
-    var raster_height=i_raster_size.h;
-    var out_index=i_out_st;
-    var cpara_6=cpara[6];
-    var cpara_0=cpara[0];
-    var cpara_3=cpara[3];
-    for(var i=0;i<i_height;i++){
-      //1列分のピクセルのインデックス値を計算する。
-      var cy0=1+i*i_step_y+i_lt_y;
-      var cpy0_12=cpara[1]*cy0+cpara[2];
-      var cpy0_45=cpara[4]*cy0+cpara[5];
-      var cpy0_7=cpara[7]*cy0+1.0;
-      var pt = 0;
-      var i2;
-      for(i2=0;i2<i_width;i2++)
-      {
-        var cx0=1+i2*i_step_x+i_lt_x;
-        var d=cpara_6*cx0+cpy0_7;
-        var x=toInt((cpara_0*cx0+cpy0_12)/d);
-        var y=toInt((cpara_3*cx0+cpy0_45)/d);
-        if(x<0||y<0||x>=raster_width||y>=raster_height)
-        {
-          return false;
-        }
-        ref_x[pt]=x;
-        ref_y[pt]=y;
-        pt++;
-      }
-      //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)
-      i_reader.getPixelSet(ref_x,ref_y,i_width,pixcel_temp);
-      //グレースケールにしながら、line→mapへの転写
-      for(i2=0;i2<i_width;i2++){
-        var index=i2;
-        o_pixel[out_index]=pixcel_temp[index];
-        out_index++;
-      }
-    }
-    return true;
-  }
-  /**
-  * i_freqにあるゼロクロス点の周期が、等間隔か調べます。
-  * 次段半周期が、前段の80%より大きく、120%未満であるものを、等間隔周期であるとみなします。
-  * @param i_freq
-  * @param i_width
-  */
-  ,checkFreqWidth : function(i_freq,i_width)
-  {
-    var c=i_freq[1]-i_freq[0];
-    var count=i_width*2-1;
-    for (var i= 1; i < count; i++) {
-      var n=i_freq[i+1]-i_freq[i];
-      var v=n*100/c;
-      if(v>150 || v<50){
-        return false;
-      }
-      c=n;
-    }
-    return true;
-  }
-  /**
-  * i_freq_count_tableとi_freq_tableの内容を調査し、最も大きな周波数成分を返します。
-  * @param i_freq_count_table
-  * @param i_freq_table
-  * @param o_freq_table
-  * @return
-  * 見つかれば0以上、密辛ければ0未満
-  */
-  ,getMaxFreq : function(i_freq_count_table,i_freq_table,o_freq_table)
-  {
-    //一番成分の大きいものを得る
-    var index=-1;
-    var max = 0;
-    var i;
-    for(i=0;i<this.MAX_FREQ;i++){
-      if(max<i_freq_count_table[i]){
-        index=i;
-        max=i_freq_count_table[i];
-      }
-    }
-    if(index==-1){
-      return -1;
-    }
-    /*周波数インデクスを計算*/
-    var st=(index-1)*index;
-    for(i=0;i<index*2;i++)
-    {
-      o_freq_table[i]=i_freq_table[st+i]*this.FRQ_STEP/max;
-    }
-    return index;
-  },
-  //タイミングパターン用のパラメタ(this.FRQ_POINTS*this.FRQ_STEPが100を超えないようにすること)
-  FRQ_EDGE : 10,
-  FRQ_STEP : 2,
-  FRQ_POINTS : (100-(5/*FRQ_EDGE*/*2))/2/*FRQ_STEP*/,
-  MIN_FREQ : 3,
-  MAX_FREQ : 10,
-  FREQ_SAMPLE_NUM : 4,
-  MAX_DATA_BITS : 10+10/*MAX_FREQ+MAX_FREQ*/-1,
-  _ref_x : new IntVector(108),
-  _ref_y : new IntVector(108),
-  //(model+1)*4*3とthis.THRESHOLD_PIXEL*3のどちらか大きい方
-  _pixcel_temp : new IntVector(108),
-  _freq_count_table : new IntVector(10/*MAX_FREQ*/),
-  _freq_table : new IntVector((10/*MAX_FREQ*/*2-1)*10/*MAX_FREQ*/*2/2),
-  /**
-  * i_y1行目とi_y2行目を平均して、タイミングパターンの周波数を得ます。
-  * LHLを1周期として、たとえばLHLHLの場合は2を返します。LHLHやHLHL等の始端と終端のレベルが異なるパターンを
-  * 検出した場合、関数は失敗します。
-  *
-  * @param i_y1
-  * @param i_y2
-  * @param i_th_h
-  * @param i_th_l
-  * @param o_edge_index
-  * 検出したエッジ位置(H->L,L->H)のインデクスを受け取る配列です。
-  * [this.FRQ_POINTS]以上の配列を指定してください。
-  * @return
-  * @throws NyARException
-  */
-  getRowFrequency : function(i_reader,i_raster_size,i_y1,i_th_h,i_th_l,o_edge_index)
-  {
-    var i;
-    //3,4,5,6,7,8,9,10
-    var freq_count_table=this._freq_count_table;
-    //0,2,4,6,8,10,12,14,16,18,20の要素を持つ配列
-    var freq_table=this._freq_table;
-    //初期化
-    var cpara=this._cparam;
-    var ref_x=this._ref_x;
-    var ref_y=this._ref_y;
-    var pixcel_temp=this._pixcel_temp;
-    for(i=0;i<10;i++){
-      freq_count_table[i]=0;
-    }
-    for(i=0;i<110;i++){
-      freq_table[i]=0;
-    }
-    var raster_width=i_raster_size.w;
-    var raster_height=i_raster_size.h;
-    var cpara_0=cpara[0];
-    var cpara_3=cpara[3];
-    var cpara_6=cpara[6];
-    var cv;
-    if (window.DEBUG) {
-      cv = document.getElementById('debugCanvas').getContext('2d');
-      cv.fillStyle = 'orange';
-    }
-    //10-20ピクセル目からタイミングパターンを検出
-    for (i = 0; i < this.FREQ_SAMPLE_NUM; i++) {
-      var i2;
-      //2行分のピクセルインデックスを計算
-      var cy0=1+i_y1+i/**this.FRQ_STEP*5+this.FRQ_EDGE*/;
-      var cpy0_12=cpara[1]*cy0+cpara[2];
-      var cpy0_45=cpara[4]*cy0+cpara[5];
-      var cpy0_7=cpara[7]*cy0+1.0;
-      var pt=0;
-      for(i2=0;i2<this.FRQ_POINTS;i2++)
-      {
-        var cx0=1+i2*this.FRQ_STEP+this.FRQ_EDGE;
-        var d=(cpara_6*cx0)+cpy0_7;
-        var x=toInt((cpara_0*cx0+cpy0_12)/d);
-        var y=toInt((cpara_3*cx0+cpy0_45)/d);
-        if(x<0||y<0||x>=raster_width||y>=raster_height)
-        {
-          return -1;
-        }
-        ref_x[pt]=x;
-        ref_y[pt]=y;
-        pt++;
-      }
-      //ピクセルを取得(入力画像を多様化するならここから先を調整すること)
-      i_reader.getPixelSet(ref_x,ref_y,this.FRQ_POINTS,pixcel_temp);
-      if (window.DEBUG) {
-        for (var j=0; j<this.FRQ_POINTS; j++) {
-          cv.fillRect(ref_x[j], ref_y[j], 1,1);
-        }
-      }
-      //o_edge_indexを一時的に破壊して調査する
-      var freq_t=this.getFreqInfo(pixcel_temp,i_th_h,i_th_l,o_edge_index);
-      //周期は3-10であること
-      if(freq_t<this.MIN_FREQ || freq_t>this.MAX_FREQ){
-        continue;
-      }
-      //周期は等間隔であること
-      if(!this.checkFreqWidth(o_edge_index,freq_t)){
-        continue;
-      }
-      //検出カウンタを追加
-      freq_count_table[freq_t]++;
-      var table_st=(freq_t-1)*freq_t;
-      for(i2=0;i2<freq_t*2;i2++){
-        freq_table[table_st+i2]+=o_edge_index[i2];
-      }
-    }
-    return this.getMaxFreq(freq_count_table,freq_table,o_edge_index);
-  }
-  ,getColFrequency : function(i_reader,i_raster_size,i_x1,i_th_h,i_th_l,o_edge_index)
-  {
-    var i;
-    var cpara=this._cparam;
-    var ref_x=this._ref_x;
-    var ref_y=this._ref_y;
-    var pixcel_temp=this._pixcel_temp;
-    //0,2,4,6,8,10,12,14,16,18,20=(11*20)/2=110
-    //初期化
-    var freq_count_table=this._freq_count_table;
-    for(i=0;i<10;i++){
-      freq_count_table[i]=0;
-    }
-    var freq_table = this._freq_table;
-    for(i=0;i<110;i++){
-      freq_table[i]=0;
-    }
-    var raster_width=i_raster_size.w;
-    var raster_height=i_raster_size.h;
-    var cpara7=cpara[7];
-    var cpara4=cpara[4];
-    var cpara1=cpara[1];
-    var cv;
-    if (window.DEBUG) {
-      cv = document.getElementById('debugCanvas').getContext('2d');
-      cv.fillStyle = 'green';
-    }
-    //基準点から4ピクセルを参照パターンとして抽出
-    for (i = 0; i < this.FREQ_SAMPLE_NUM; i++) {
-      var i2;
-      var cx0=1+i/**this.FRQ_STEP*5+this.FRQ_EDGE*/+i_x1;
-      var cp6_0=cpara[6]*cx0;
-      var cpx0_0=cpara[0]*cx0+cpara[2];
-      var cpx3_0=cpara[3]*cx0+cpara[5];
-      var pt=0;
-      for(i2=0;i2<this.FRQ_POINTS;i2++)
-      {
-        var cy=1+i2*this.FRQ_STEP+this.FRQ_EDGE;
-        var d=cp6_0+cpara7*cy+1.0;
-        var x=toInt((cpx0_0+cpara1*cy)/d);
-        var y=toInt((cpx3_0+cpara4*cy)/d);
-        if(x<0||y<0||x>=raster_width||y>=raster_height)
-        {
-          return -1;
-        }
-        ref_x[pt]=x;
-        ref_y[pt]=y;
-        pt++;
-      }
-      //ピクセルを取得(入力画像を多様化するならここを調整すること)
-      i_reader.getPixelSet(ref_x,ref_y,this.FRQ_POINTS,pixcel_temp);
-      if (window.DEBUG) {
-        for (var j=0; j<this.FRQ_POINTS; j++) {
-          cv.fillRect(ref_x[j], ref_y[j], 1,1);
-        }
-      }
-      var freq_t=this.getFreqInfo(pixcel_temp,i_th_h,i_th_l,o_edge_index);
-      //周期は3-10であること
-      if(freq_t<this.MIN_FREQ || freq_t>this.MAX_FREQ){
-        continue;
-      }
-      //周期は等間隔であること
-      if(!this.checkFreqWidth(o_edge_index,freq_t)){
-        continue;
-      }
-      //検出カウンタを追加
-      freq_count_table[freq_t]++;
-      var table_st=(freq_t-1)*freq_t;
-      for(i2=0;i2<freq_t*2;i2++){
-        freq_table[table_st+i2]+=o_edge_index[i2];
-      }
-    }
-    return this.getMaxFreq(freq_count_table,freq_table,o_edge_index);
-  }
-  /**
-  * デバックすんだらstaticにしておｋ
-  * @param i_pixcels
-  * @param i_th_h
-  * @param i_th_l
-  * @param o_edge_index
-  * @return
-  */
-  ,getFreqInfo : function(i_pixcels,i_th_h,i_th_l,o_edge_index)
-  {
-    //トークンを解析して、周波数を計算
-    var i=0;
-    var frq_l2h=0;
-    var frq_h2l = 0;
-    var index,pix;
-    while(i<this.FRQ_POINTS){
-      //L->Hトークンを検出する
-      while(i<this.FRQ_POINTS){
-        index=i;
-        pix=i_pixcels[index];
-        if(pix>i_th_h){
-          //トークン発見
-          o_edge_index[frq_l2h+frq_h2l]=i;
-          frq_l2h++;
-          break;
-        }
-        i++;
-      }
-      i++;
-      //L->Hトークンを検出する
-      while(i<this.FRQ_POINTS){
-        index=i;
-        pix=i_pixcels[index];
-        if(pix<=i_th_l){
-          //トークン発見
-          o_edge_index[frq_l2h+frq_h2l]=i;
-          frq_h2l++;
-          break;
-        }
-        i++;
-      }
-      i++;
-    }
-    return frq_l2h==frq_h2l?frq_l2h:-1;
-  },
-  THRESHOLD_EDGE : 10,
-  THRESHOLD_STEP : 2,
-  THRESHOLD_WIDTH : 10,
-  THRESHOLD_PIXEL : 10/2/*this.THRESHOLD_WIDTH/this.THRESHOLD_STEP*/,
-  THRESHOLD_SAMPLE : 5*5/*this.THRESHOLD_PIXEL*this.THRESHOLD_PIXEL*/,
-  THRESHOLD_SAMPLE_LT : 10/*this.THRESHOLD_EDGE*/,
-  THRESHOLD_SAMPLE_RB : 100-10-10/*this.THRESHOLD_WIDTH-this.THRESHOLD_EDGE*/,
-  /**
-  * ピクセル配列の上位、下位の4ピクセルのピクセル値平均を求めます。
-  * この関数は、(4/i_pixcel.length)の領域を占有するPtail法で双方向の閾値を求めることになります。
-  * @param i_pixcel
-  * @param i_initial
-  * @param i_out
-  */
-  getPtailHighAndLow : function(i_pixcel,i_out )
-  {
-    var h3,h2,h1,h0,l3,l2,l1,l0;
-    h3=h2=h1=h0=l3=l2=l1=l0=i_pixcel[0];
-    for(var i=i_pixcel.length-1;i>=1;i--){
-      var pix=i_pixcel[i];
-      if(h0<pix){
-        if(h1<pix){
-          if(h2<pix){
-            if(h3<pix){
-              h0=h1;
-              h1=h2;
-              h2=h3;
-              h3=pix;
-            }else{
-              h0=h1;
-              h1=h2;
-              h2=pix;
-            }
-          }else{
-            h0=h1;
-            h1=pix;
-          }
-        }else{
-          h0=pix;
-        }
-      }
-      if(l0>pix){
-        if(l1>pix){
-          if(l2>pix){
-            if(l3>pix){
-              l0=l1;
-              l1=l2;
-              l2=l3;
-              l3=pix;
-            }else{
-              l0=l1;
-              l1=l2;
-              l2=pix;
-            }
-          }else{
-            l0=l1;
-            l1=pix;
-          }
-        }else{
-          l0=pix;
-        }
-      }
-    }
-    i_out.l=(l0+l1+l2+l3)/4;
-    i_out.h=(h0+h1+h2+h3)/4;
-    return;
-  },
-  __detectThresholdValue_hl : new THighAndLow(),
-  __detectThresholdValue_tpt : new NyARIntPoint2d(),
-  _th_pixels : new IntVector(5*5/*this.THRESHOLD_SAMPLE*/*4),
-  /**
-  * 指定した場所のピクセル値を調査して、閾値を計算して返します。
-  * @param i_reader
-  * @param i_x
-  * @param i_y
-  * @return
-  * @throws NyARException
-  */
-  detectThresholdValue : function(i_reader,i_raster_size,o_threshold)
-  {
-    var th_pixels=this._th_pixels;
-    //左上のピックアップ領域からピクセルを得る(00-24)
-    this.rectPixels(i_reader,i_raster_size,this.THRESHOLD_SAMPLE_LT,this.THRESHOLD_SAMPLE_LT,this.THRESHOLD_STEP,this.THRESHOLD_STEP,this.THRESHOLD_PIXEL,this.THRESHOLD_PIXEL,0,th_pixels);
-    //左下のピックアップ領域からピクセルを得る(25-49)
-    this.rectPixels(i_reader,i_raster_size,this.THRESHOLD_SAMPLE_LT,this.THRESHOLD_SAMPLE_RB,this.THRESHOLD_STEP,this.THRESHOLD_STEP,this.THRESHOLD_PIXEL,this.THRESHOLD_PIXEL,this.THRESHOLD_SAMPLE,th_pixels);
-    //右上のピックアップ領域からピクセルを得る(50-74)
-    this.rectPixels(i_reader,i_raster_size,this.THRESHOLD_SAMPLE_RB,this.THRESHOLD_SAMPLE_LT,this.THRESHOLD_STEP,this.THRESHOLD_STEP,this.THRESHOLD_PIXEL,this.THRESHOLD_PIXEL,this.THRESHOLD_SAMPLE*2,th_pixels);
-    //右下のピックアップ領域からピクセルを得る(75-99)
-    this.rectPixels(i_reader,i_raster_size,this.THRESHOLD_SAMPLE_RB,this.THRESHOLD_SAMPLE_RB,this.THRESHOLD_STEP,this.THRESHOLD_STEP,this.THRESHOLD_PIXEL,this.THRESHOLD_PIXEL,this.THRESHOLD_SAMPLE*3,th_pixels);
-    var hl=this.__detectThresholdValue_hl;
-    //Ptailで求めたピクセル平均
-    this.getPtailHighAndLow(th_pixels,hl);
-    //閾値中心
-    var th=(hl.h+hl.l)/2;
-    //ヒステリシス(差分の20%)
-    var th_sub=(hl.h-hl.l)/5;
-    o_threshold.th=th;
-    o_threshold.th_h=th+th_sub;//ヒステリシス付き閾値
-    o_threshold.th_l=th-th_sub;//ヒステリシス付き閾値
-    //エッジを計算(明点重心)
-    var lt_x,lt_y,lb_x,lb_y,rt_x,rt_y,rb_x,rb_y;
-    var tpt=this.__detectThresholdValue_tpt;
-    //LT
-    if(this.getHighPixelCenter(0,th_pixels,this.THRESHOLD_PIXEL,this.THRESHOLD_PIXEL,th,tpt)){
-      lt_x=tpt.x*this.THRESHOLD_STEP;
-      lt_y=tpt.y*this.THRESHOLD_STEP;
-    }else{
-      lt_x=11;
-      lt_y=11;
-    }
-    //LB
-    if(this.getHighPixelCenter(this.THRESHOLD_SAMPLE*1,th_pixels,this.THRESHOLD_PIXEL,this.THRESHOLD_PIXEL,th,tpt)){
-      lb_x=tpt.x*this.THRESHOLD_STEP;
-      lb_y=tpt.y*this.THRESHOLD_STEP;
-    }else{
-      lb_x=11;
-      lb_y=-1;
-    }
-    //RT
-    if(this.getHighPixelCenter(this.THRESHOLD_SAMPLE*2,th_pixels,this.THRESHOLD_PIXEL,this.THRESHOLD_PIXEL,th,tpt)){
-      rt_x=tpt.x*this.THRESHOLD_STEP;
-      rt_y=tpt.y*this.THRESHOLD_STEP;
-    }else{
-      rt_x=-1;
-      rt_y=11;
-    }
-    //RB
-    if(this.getHighPixelCenter(this.THRESHOLD_SAMPLE*3,th_pixels,this.THRESHOLD_PIXEL,this.THRESHOLD_PIXEL,th,tpt)){
-      rb_x=tpt.x*this.THRESHOLD_STEP;
-      rb_y=tpt.y*this.THRESHOLD_STEP;
-    }else{
-      rb_x=-1;
-      rb_y=-1;
-    }
-    //トラッキング開始位置の決定
-    o_threshold.lt_x=(lt_x+lb_x)/2+this.THRESHOLD_SAMPLE_LT-1;
-    o_threshold.rb_x=(rt_x+rb_x)/2+this.THRESHOLD_SAMPLE_RB+1;
-    o_threshold.lt_y=(lt_y+rt_y)/2+this.THRESHOLD_SAMPLE_LT-1;
-    o_threshold.rb_y=(lb_y+rb_y)/2+this.THRESHOLD_SAMPLE_RB+1;
-    return;
-  }
-  ,getHighPixelCenter : function(i_st,i_pixels,i_width,i_height,i_th,o_point)
-  {
-    var rp=i_st;
-    var pos_x=0;
-    var pos_y=0;
-    var number_of_pos=0;
-    for(var i=0;i<i_height;i++){
-      for(var i2=0;i2<i_width;i2++){
-        if(i_pixels[rp++]>i_th){
-          pos_x+=i2;
-          pos_y+=i;
-          number_of_pos++;
-        }
-      }
-    }
-    if(number_of_pos>0){
-      pos_x/=number_of_pos;
-      pos_y/=number_of_pos;
-    }else{
-      return false;
-    }
-    o_point.x=pos_x;
-    o_point.y=pos_y;
-    return true;
-  },
-  __detectDataBitsIndex_freq_index1 : new IntVector((100-(5*2))/2/*this.FRQ_POINTS*/),
-  __detectDataBitsIndex_freq_index2 : new IntVector((100-(5*2))/2/*this.FRQ_POINTS*/),
-  detectDataBitsIndex : function(i_reader,i_raster_size,i_th,o_index_row,o_index_col)
-  {
-    var i;
-    //周波数を測定
-    var freq_index1=this.__detectDataBitsIndex_freq_index1;
-    var freq_index2=this.__detectDataBitsIndex_freq_index2;
-    var lydiff = i_th.rb_y-i_th.lt_y;
-    var frq_t=this.getRowFrequency(i_reader,i_raster_size,i_th.lt_y/*-0.25*this.FRQ_EDGE*/,i_th.th_h,i_th.th_l,freq_index1);
-    var frq_b=this.getRowFrequency(i_reader,i_raster_size,i_th.rb_y/*-0.5*lydiff*/,i_th.th_h,i_th.th_l,freq_index2);
-    //周波数はまとも？
-    if((frq_t<0 && frq_b<0) || frq_t==frq_b){
-      if (window.DEBUG)
-        console.log('bad row frq', frq_t, frq_b)
-      return -1;
-    }
-    //タイミングパターンからインデクスを作成
-    var freq_h,freq_v;
-    var index;
-    if(frq_t>frq_b){
-      freq_h=frq_t;
-      index=freq_index1;
-    }else{
-      freq_h=frq_b;
-      index=freq_index2;
-    }
-    for(i=0;i<freq_h+freq_h-1;i++){
-      o_index_row[i*2]=((index[i+1]-index[i])*2/5+index[i])+this.FRQ_EDGE;
-      o_index_row[i*2+1]=((index[i+1]-index[i])*3/5+index[i])+this.FRQ_EDGE;
-    }
-    var lxdiff = i_th.rb_x-i_th.lt_x;
-    var frq_l=this.getColFrequency(i_reader,i_raster_size,i_th.lt_x/*-0.25*this.FRQ_EDGE*/,i_th.th_h,i_th.th_l,freq_index1);
-    var frq_r=this.getColFrequency(i_reader,i_raster_size,i_th.rb_x/*-0.5*lxdiff*/,i_th.th_h,i_th.th_l,freq_index2);
-    //周波数はまとも？
-    if((frq_l<0 && frq_r<0) || frq_l==frq_r){
-      if (window.DEBUG)
-        console.log('bad col frq', frq_l, frq_r);
-      return -1;
-    }
-    //タイミングパターンからインデクスを作成
-    if(frq_l>frq_r){
-      freq_v=frq_l;
-      index=freq_index1;
-    }else{
-      freq_v=frq_r;
-      index=freq_index2;
-    }
-    //同じ周期？
-    if(freq_v!=freq_h){
-      if (window.DEBUG)
-        console.log('freq mismatch', freq_v, freq_h)
-      return -1;
-    }
-    for(i=0;i<freq_v+freq_v-1;i++){
-      var w=index[i];
-      var w2= index[i + 1] - w;
-      o_index_col[i*2]=((w2)*2/5+w)+this.FRQ_EDGE;
-      o_index_col[i*2+1]=((w2)*3/5+w)+this.FRQ_EDGE;
-    }
-    //Lv4以上は無理
-    if(freq_v>this.MAX_FREQ){
-      if (window.DEBUG)
-        console.log('too high freq', freq_v)
-      return -1;
-    }
-    return freq_v;
-  },
-  __readDataBits_index_bit_x : new FloatVector(19/*MAX_DATA_BITS*/*2),
-  __readDataBits_index_bit_y : new FloatVector(19/*MAX_DATA_BITS*/*2),
-  previousFrames : {},
-  centerPoint : new IntVector(2),
-  getPreviousFrameSize : function(index_x, index_y) {
-    var cx = this.centerPoint[0], cy = this.centerPoint[1];
-    var pfs = this.previousFrames;
-    var pf = (
-      pfs[cx+":"+cy] || pfs[(cx-1)+":"+cy] || pfs[(cx+1)+":"+cy] ||
-      pfs[cx+":"+(cy-1)] || pfs[(cx-1)+":"+(cy-1)] || pfs[(cx+1)+":"+(cy-1)] ||
-      pfs[cx+":"+(cy+1)] || pfs[(cx-1)+":"+(cy+1)] || pfs[(cx+1)+":"+(cy+1)]
-    );
-    if (!pf)
-      return -1;
-    index_x.set(pf.index_x);
-    index_y.set(pf.index_y);
-    return pf.size;
-  },
-  setPreviousFrameSize : function(size, index_x, index_y) {
-    var pf = this.previousFrames[this.centerPoint[0]+":"+this.centerPoint[1]];
-    if (!pf) {
-      pf = {age: 0, size: size, index_x: new FloatVector(index_x), index_y: new FloatVector(index_y)};
-      this.previousFrames[this.centerPoint[0]+":"+this.centerPoint[1]] = pf;
-      return;
-    }
-    pf.age = 0;
-    pf.size = size;
-    pf.index_x.set(index_x);
-    pf.index_y.set(index_y);
-  },
-  readDataBits : function(i_reader, i_raster_size, i_th, o_bitbuffer)
-  {
-    var index_x=this.__readDataBits_index_bit_x;
-    var index_y=this.__readDataBits_index_bit_y;
-    //読み出し位置を取得
-    var size=this.detectDataBitsIndex(i_reader,i_raster_size,i_th,index_x,index_y);
-    if (size<0) {
-      size = this.getPreviousFrameSize(index_x, index_y);
-    }
-    var resolution=size+size-1;
-    if(size<0){
-      if (window.DEBUG)
-        console.log('readDataBits: size < 0');
-      return false;
-    }
-    if(!o_bitbuffer.initEncoder(size-1)){
-      if (window.DEBUG)
-        console.log('readDataBits: initEncoder');
-      return false;
-    }
-    var cpara=this._cparam;
-    var ref_x=this._ref_x;
-    var ref_y=this._ref_y;
-    var pixcel_temp=this._pixcel_temp;
-    var cpara_0=cpara[0];
-    var cpara_1=cpara[1];
-    var cpara_3=cpara[3];
-    var cpara_6=cpara[6];
-    var th=i_th.th;
-    var p=0;
-    for (var i = 0; i < resolution; i++) {
-      var i2;
-      //1列分のピクセルのインデックス値を計算する。
-      var cy0=1+index_y[i*2+0];
-      var cy1=1+index_y[i*2+1];
-      var cpy0_12=cpara_1*cy0+cpara[2];
-      var cpy0_45=cpara[4]*cy0+cpara[5];
-      var cpy0_7=cpara[7]*cy0+1.0;
-      var cpy1_12=cpara_1*cy1+cpara[2];
-      var cpy1_45=cpara[4]*cy1+cpara[5];
-      var cpy1_7=cpara[7]*cy1+1.0;
-      var pt=0;
-      for(i2=0;i2<resolution;i2++)
-      {
-        var d;
-        var cx0=1+index_x[i2*2+0];
-        var cx1=1+index_x[i2*2+1];
-        var cp6_0=cpara_6*cx0;
-        var cpx0_0=cpara_0*cx0;
-        var cpx3_0=cpara_3*cx0;
-        var cp6_1=cpara_6*cx1;
-        var cpx0_1=cpara_0*cx1;
-        var cpx3_1=cpara_3*cx1;
-        d=cp6_0+cpy0_7;
-        ref_x[pt]=toInt((cpx0_0+cpy0_12)/d);
-        ref_y[pt]=toInt((cpx3_0+cpy0_45)/d);
-        pt++;
-        d=cp6_0+cpy1_7;
-        ref_x[pt]=toInt((cpx0_0+cpy1_12)/d);
-        ref_y[pt]=toInt((cpx3_0+cpy1_45)/d);
-        pt++;
-        d=cp6_1+cpy0_7;
-        ref_x[pt]=toInt((cpx0_1+cpy0_12)/d);
-        ref_y[pt]=toInt((cpx3_1+cpy0_45)/d);
-        pt++;
-        d=cp6_1+cpy1_7;
-        ref_x[pt]=toInt((cpx0_1+cpy1_12)/d);
-        ref_y[pt]=toInt((cpx3_1+cpy1_45)/d);
-        pt++;
-      }
-      //1行分のピクセルを取得(場合によっては専用アクセサを書いた方がいい)
-      i_reader.getPixelSet(ref_x,ref_y,resolution*4,pixcel_temp);
-      //グレースケールにしながら、line→mapへの転写
-      for(i2=0;i2<resolution;i2++){
-        var index=i2*4;
-        var pixel=(pixcel_temp[index+0]+pixcel_temp[index+1]+pixcel_temp[index+2]+pixcel_temp[index+3])/(4);
-        //暗点を1、明点を0で表現します。
-        o_bitbuffer.setBitByBitIndex(p,pixel>th?0:1);
-        p++;
-      }
-    }
-    this.setPreviousFrameSize(size, index_x, index_y);
-    return true;
-  }
-  ,setSquare : function(i_vertex)
-  {
-    if (!this._param_gen.getParam(i_vertex,this._cparam)) {
-      return false;
-    }
-    return true;
-  }
-})
-MarkerPattDecoder = ASKlass('MarkerPattDecoder',
-{
-  decode : function(model,domain,mask)
-  {
-  }
-})
-
-INyIdMarkerDataEncoder = ASKlass('INyIdMarkerDataEncoder',
-{
-  encode : function(i_data,o_dest){},
-  createDataInstance : function(){}
-})
-NyIdMarkerDataEncoder_RawBit = ASKlass('NyIdMarkerDataEncoder_RawBit', INyIdMarkerDataEncoder,
-{
-  _DOMAIN_ID : 0,
-  _mod_data : new IntVector([7,31,127,511,2047,4095]),
-  encode : function(i_data,o_dest)
-  {
-    var dest=(o_dest);
-    if(i_data.ctrl_domain!=this._DOMAIN_ID){
-      return false;
-    }
-    // calculate marker resolution (amount of data dots per side)
-    var resolution_len = (i_data.model * 2 - 1); //trace("resolution", resolution_len);
-    // there are (2*model-1)^2 data dots in a marker
-    // and the amount of packets in a marker is
-    // floor(dataDotCount / 8) + 1  (the +1 is packet 0)
-    var packet_length = (((resolution_len * resolution_len)) / 8) + 1; //trace("packet", packet_length);
-    var sum = 0;
-    for(var i=0;i<packet_length;i++){
-      dest.packet[i] = i_data.data[i]; //trace("i_data[",i,"]",i_data.data[i]);
-      sum += i_data.data[i];
-    }
-    // data point check sum calculation
-    sum = sum % this._mod_data[i_data.model - 2]; //trace("check dot", i_data.check, sum);
-    // compare data point check sum with expected
-    if(i_data.check!=sum){
-      return false;
-    }
-    dest.length=packet_length;
-    return true;
-  }
-  ,createDataInstance : function()
-  {
-    return new NyIdMarkerData_RawBit();
-  }
-})
-NyIdMarkerData_RawBit = ASKlass('NyIdMarkerData_RawBit', INyIdMarkerData,
-{
-  packet : new IntVector(22),
-  length : 0,
-  isEqual : function(i_target)
-  {
-    var s=(i_target);
-    if(s.length!=this.length){
-      return false;
-    }
-    for(var i=s.length-1;i>=0;i--){
-      if(s.packet[i]!=this.packet[i]){
-        return false;
-      }
-    }
-    return true;
-  }
-  ,copyFrom : function(i_source)
-  {
-    var s=(i_source);
-    ArrayUtils.copyInt(s.packet,0,this.packet,0,s.length);
-    this.length=s.length;
-    return;
-  }
-})
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * JSARToolkit
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- *   Hirokazu Kato
- *   Mark Billinghurst
- *   HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * And the NyARToolkitAS3 ARToolKit class library.
- *   Copyright (C)2010 Ryo Iizuka
- *
- * JSARToolkit is a JavaScript port of NyARToolkitAS3.
- *   Copyright (C)2010 Ilmari Heikkinen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  ilmari.heikkinen@gmail.com
- *
- */
-INyARColorPatt = ASKlass('INyARColorPatt', INyARRgbRaster,
-{
-  /**
-   * ラスタイメージからi_square部分のカラーパターンを抽出して、thisメンバに格納します。
-   *
-   * @param image
-   * Source raster object.
-   * ----
-   * 抽出元のラスタオブジェクト
-   * @param i_vertexs
-   * Vertexes of the square. Number of element must be 4.
-   * ----
-   * 射影変換元の４角形を構成する頂点群頂群。要素数は4であること。
-   * @return
-   * True if sucessfull; otherwise false.
-   * ----
-   * ラスターの取得に成功するとTRUE/失敗するとFALSE
-   * @throws NyARException
-   */
-//  public boolean pickFromRaster(INyARRgbRaster image, NyARSquare i_square) throws NyARException;
-  pickFromRaster : function(image,i_vertexs){}
-})
-NyARColorPatt_Perspective = ASKlass('NyARColorPatt_Perspective', INyARColorPatt,
-{
-  _patdata : null,
-  _pickup_lt : new NyARIntPoint2d(),
-  _resolution : 0,
-  _size : null,
-  _perspective_gen : null,
-  _pixelreader : null,
-  LOCAL_LT : 1,
-  BUFFER_FORMAT : NyARBufferType.INT1D_X8R8G8B8_32,
-  initializeInstance : function(i_width,i_height,i_point_per_pix)
-  {
-    NyAS3Utils.assert(i_width>2 && i_height>2);
-    this._resolution=i_point_per_pix;
-    this._size=new NyARIntSize(i_width,i_height);
-    this._patdata = new IntVector(i_height*i_width);
-    this._pixelreader=new NyARRgbPixelReader_INT1D_X8R8G8B8_32(this._patdata,this._size);
-    return;
-  }
-  /**
-   * 例えば、64
-   * @param i_width
-   * 取得画像の解像度幅
-   * @param i_height
-   * 取得画像の解像度高さ
-   */
-  /**
-   * 例えば、64
-   * @param i_width
-   * 取得画像の解像度幅
-   * @param i_height
-   * 取得画像の解像度高さ
-   * @param i_point_per_pix
-   * 1ピクセルあたりの縦横サンプリング数。2なら2x2=4ポイントをサンプリングする。
-   * @param i_edge_percentage
-   * エッジ幅の割合(ARToolKit標準と同じなら、25)
-   */
-  ,NyARColorPatt_Perspective : function(i_width,i_height,i_point_per_pix,i_edge_percentage)
-  {
-    if (i_edge_percentage == null) i_edge_percentage = -1;
-    if (i_edge_percentage == -1) {
-      this.initializeInstance(i_width,i_height,i_point_per_pix);
-      this.setEdgeSize(0,0,i_point_per_pix);
-    }else{
-      //入力制限
-      this.initializeInstance(i_width,i_height,i_point_per_pix);
-      this.setEdgeSizeByPercent(i_edge_percentage, i_edge_percentage, i_point_per_pix);
-    }
-    return;
-  }
-  /**
-   * 矩形領域のエッジサイズを指定します。
-   * エッジの計算方法は以下の通りです。
-   * 1.マーカ全体を(i_x_edge*2+width)x(i_y_edge*2+height)の解像度でパラメタを計算します。
-   * 2.ピクセルの取得開始位置を(i_x_edge/2,i_y_edge/2)へ移動します。
-   * 3.開始位置から、width x height個のピクセルを取得します。
-   *
-   * ARToolKit標準マーカの場合は、width/2,height/2を指定してください。
-   * @param i_x_edge
-   * @param i_y_edge
-   */
-  ,setEdgeSize : function(i_x_edge,i_y_edge,i_resolution)
-  {
-    NyAS3Utils.assert(i_x_edge>=0);
-    NyAS3Utils.assert(i_y_edge>=0);
-    //Perspectiveパラメタ計算器を作成
-    this._perspective_gen=new NyARPerspectiveParamGenerator_O1(
-      this.LOCAL_LT,this.LOCAL_LT,
-      (i_x_edge*2+this._size.w)*i_resolution,
-      (i_y_edge*2+this._size.h)*i_resolution);
-    //ピックアップ開始位置を計算
-    this._pickup_lt.x=i_x_edge*i_resolution+this.LOCAL_LT;
-    this._pickup_lt.y=i_y_edge*i_resolution+this.LOCAL_LT;
-    return;
-  }
-  ,setEdgeSizeByPercent : function(i_x_percent,i_y_percent,i_resolution)
-  {
-    NyAS3Utils.assert(i_x_percent>=0);
-    NyAS3Utils.assert(i_y_percent>=0);
-    this.setEdgeSize(this._size.w*i_x_percent/50,this._size.h*i_y_percent/50,i_resolution);
-    return;
-  }
-  ,getWidth : function()
-  {
-    return this._size.w;
-  }
-  ,getHeight : function()
-  {
-    return this._size.h;
-  }
-  ,getSize : function()
-  {
-    return   this._size;
-  }
-  ,getRgbPixelReader : function()
-  {
-    return this._pixelreader;
-  }
-  ,getBuffer : function()
-  {
-    return this._patdata;
-  }
-  ,hasBuffer : function()
-  {
-    return this._patdata!=null;
-  }
-  ,wrapBuffer : function(i_ref_buf)
-  {
-    NyARException.notImplement();
-  }
-  ,getBufferType : function()
-  {
-    return BUFFER_FORMAT;
-  }
-  ,isEqualBufferType : function(i_type_value)
-  {
-    return BUFFER_FORMAT==i_type_value;
-  },
-  __pickFromRaster_rgb_tmp : new IntVector(3),
-  __pickFromRaster_cpara : new FloatVector(8),
-  /**
-   * @see INyARColorPatt#pickFromRaster
-   */
-  pickFromRaster : function(image,i_vertexs)
-  {
-    //遠近法のパラメータを計算
-    var cpara = this.__pickFromRaster_cpara;
-    if (!this._perspective_gen.getParam(i_vertexs, cpara)) {
-      return false;
-    }
-    var resolution=this._resolution;
-    var img_x = image.getWidth();
-    var img_y = image.getHeight();
-    var res_pix=resolution*resolution;
-    var rgb_tmp = this.__pickFromRaster_rgb_tmp;
-    //ピクセルリーダーを取得
-    var reader =image.getRgbPixelReader();
-    var p=0;
-    for(var iy=0;iy<this._size.h*resolution;iy+=resolution){
-      //解像度分の点を取る。
-      for(var ix=0;ix<this._size.w*resolution;ix+=resolution){
-        var r,g,b;
-        r=g=b=0;
-        for(var i2y=iy;i2y<iy+resolution;i2y++){
-          var cy=this._pickup_lt.y+i2y;
-          for(var i2x=ix;i2x<ix+resolution;i2x++){
-            //1ピクセルを作成
-            var cx=this._pickup_lt.x+i2x;
-            var d=cpara[6]*cx+cpara[7]*cy+1.0;
-            var x=toInt((cpara[0]*cx+cpara[1]*cy+cpara[2])/d);
-            var y=toInt((cpara[3]*cx+cpara[4]*cy+cpara[5])/d);
-            if(x<0){x=0;}
-            if(x>=img_x){x=img_x-1;}
-            if(y<0){y=0;}
-            if(y>=img_y){y=img_y-1;}
-            reader.getPixel(x, y, rgb_tmp);
-            r+=rgb_tmp[0];
-            g+=rgb_tmp[1];
-            b+=rgb_tmp[2];
-          }
-        }
-        r/=res_pix;
-        g/=res_pix;
-        b/=res_pix;
-        this._patdata[p]=((r&0xff)<<16)|((g&0xff)<<8)|((b&0xff));
-        p++;
-      }
-    }
-      //ピクセル問い合わせ
-      //ピクセルセット
-    return true;
-  }
-})
-NyARColorPatt_Perspective_O2 = ASKlass('NyARColorPatt_Perspective_O2', NyARColorPatt_Perspective,
-{
-  _pickup : null,
-  NyARColorPatt_Perspective_O2 : function(i_width,i_height,i_resolution,i_edge_percentage)
-  {
-    NyARColorPatt_Perspective.initialize.call(this,i_width,i_height,i_resolution,i_edge_percentage);
-    switch(i_resolution){
-    case 1:
-      this._pickup=new NyARPickFromRaster_1(this._pickup_lt,this._size);
-      break;
-    case 2:
-      this._pickup=new NyARPickFromRaster_2x(this._pickup_lt,this._size);
-      break;
-    case 4:
-      this._pickup=new NyARPickFromRaster_4x(this._pickup_lt,this._size);
-      break;
-    default:
-      this._pickup=new NyARPickFromRaster_N(this._pickup_lt,i_resolution,this._size);
-    }
-    return;
-  }
-  /**
-   * @see INyARColorPatt#pickFromRaster
-   */
-  ,pickFromRaster : function(image ,i_vertexs)
-  {
-    //遠近法のパラメータを計算
-    var cpara = this.__pickFromRaster_cpara;
-    if (!this._perspective_gen.getParam(i_vertexs, cpara)) {
-      return false;
-    }
-    this._pickup.pickFromRaster(cpara, image,this._patdata);
-    return true;
-  }
-})
-
-IpickFromRaster_Impl = ASKlass('IpickFromRaster_Impl',
-{
-  pickFromRaster : function(i_cpara,image,o_patt){}
-})
-
-
-
-/**
- * チェックデジット:4127936236942444153655776299710081208144715171590159116971715177917901890204024192573274828522936312731813388371037714083
- *
- */
-NyARPickFromRaster_1 = ASKlass('NyARPickFromRaster_1', IpickFromRaster_Impl,
-{
-  _size_ref : null,
-  _lt_ref : null,
-  NyARPickFromRaster_1 : function(i_lt,i_source_size)
-  {
-    this._lt_ref=i_lt;
-    this._size_ref=i_source_size;
-    this._rgb_temp=new IntVector(i_source_size.w*3);
-    this._rgb_px=new IntVector(i_source_size.w);
-    this._rgb_py=new IntVector(i_source_size.w);
-    return;
-  },
-  _rgb_temp : null,
-  _rgb_px : null,
-  _rgb_py : null,
-  pickFromRaster : function(i_cpara, image, o_patt)
-  {
-    var d0,m0;
-    var x,y;
-    var img_x = image.getWidth();
-    var img_y = image.getHeight();
-    var patt_w=this._size_ref.w;
-    var rgb_tmp = this._rgb_temp;
-    var rgb_px=this._rgb_px;
-    var rgb_py=this._rgb_py;
-    var cp0=i_cpara[0];
-    var cp3=i_cpara[3];
-    var cp6=i_cpara[6];
-    var cp1=i_cpara[1];
-    var cp4=i_cpara[4];
-    var cp7=i_cpara[7];
-    var pick_y=this._lt_ref.y;
-    var pick_x=this._lt_ref.x;
-    //ピクセルリーダーを取得
-    var reader=image.getRgbPixelReader();
-    var p=0;
-    var cp0cx0,cp3cx0;
-    var cp1cy_cp20=cp1*pick_y+i_cpara[2]+cp0*pick_x;
-    var cp4cy_cp50=cp4*pick_y+i_cpara[5]+cp3*pick_x;
-    var cp7cy_10=cp7*pick_y+1.0+cp6*pick_x;
-    for(var iy=this._size_ref.h-1;iy>=0;iy--){
-      m0=1/(cp7cy_10);
-      d0=-cp6/(cp7cy_10*(cp7cy_10+cp6));
-      cp0cx0=cp1cy_cp20;
-      cp3cx0=cp4cy_cp50;
-      //ピックアップシーケンス
-      //0番目のピクセル(検査対象)をピックアップ
-      var ix;
-      for(ix=patt_w-1;ix>=0;ix--){
-        //1ピクセルを作成
-        x=rgb_px[ix]=toInt(cp0cx0*m0);
-        y=rgb_py[ix]=toInt(cp3cx0*m0);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[ix]=0;}else if(x>=img_x){rgb_px[ix]=img_x-1;}
-          if(y<0){rgb_py[ix]=0;}else if(y>=img_y){rgb_py[ix]=img_y-1;}
-        }
-        cp0cx0+=cp0;
-        cp3cx0+=cp3;
-        m0+=d0;
-      }
-      cp1cy_cp20+=cp1;
-      cp4cy_cp50+=cp4;
-      cp7cy_10+=cp7;
-      reader.getPixelSet(rgb_px, rgb_py,patt_w, rgb_tmp);
-      for(ix=patt_w-1;ix>=0;ix--){
-        var idx=ix*3;
-        o_patt[p]=(rgb_tmp[idx]<<16)|(rgb_tmp[idx+1]<<8)|((rgb_tmp[idx+2]&0xff));
-        p++;
-      }
-    }
-    return;
-  }
-})
-/*
-* PROJECT: NyARToolkitAS3
-* --------------------------------------------------------------------------------
-* This work is based on the original ARToolKit developed by
-*   Hirokazu Kato
-*   Mark Billinghurst
-*   HITLab, University of Washington, Seattle
-* http://www.hitl.washington.edu/artoolkit/
-*
-* The NyARToolkitAS3 is AS3 edition ARToolKit class library.
-* Copyright (C)2010 Ryo Iizuka
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*
-* For further information please contact.
-*  http://nyatla.jp/nyatoolkit/
-*  <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
-*
-*/
-
-
-
-
-/**
- * 2x2
- * チェックデジット:207585881161241401501892422483163713744114324414474655086016467027227327958629279571017
- *
- */
-NyARPickFromRaster_2x = ASKlass('NyARPickFromRaster_2x', IpickFromRaster_Impl,
-{
-  _size_ref : null,
-  _lt_ref : null,
-  NyARPickFromRaster_2x : function(i_lt,i_source_size)
-  {
-    this._lt_ref=i_lt;
-    this._size_ref=i_source_size;
-    this._rgb_temp=new IntVector(i_source_size.w*4*3);
-    this._rgb_px=new IntVector(i_source_size.w*4);
-    this._rgb_py=new IntVector(i_source_size.w*4);
-    return;
-  },
-  _rgb_temp : null,
-  _rgb_px : null,
-  _rgb_py : null,
-  pickFromRaster : function(i_cpara,image,o_patt)
-  {
-    var d0,m0,d1,m1;
-    var x,y;
-    var img_x = image.getWidth();
-    var img_y = image.getHeight();
-    var patt_w=this._size_ref.w;
-    var rgb_tmp = this._rgb_temp;
-    var rgb_px=this._rgb_px;
-    var rgb_py=this._rgb_py;
-    var cp0=i_cpara[0];
-    var cp3=i_cpara[3];
-    var cp6=i_cpara[6];
-    var cp1=i_cpara[1];
-    var cp4=i_cpara[4];
-    var cp7=i_cpara[7];
-    var pick_y=this._lt_ref.y;
-    var pick_x=this._lt_ref.x;
-    //ピクセルリーダーを取得
-    var reader=image.getRgbPixelReader();
-    var p=0;
-    var cp0cx0,cp3cx0;
-    var cp1cy_cp20=cp1*pick_y+i_cpara[2]+cp0*pick_x;
-    var cp4cy_cp50=cp4*pick_y+i_cpara[5]+cp3*pick_x;
-    var cp7cy_10=cp7*pick_y+1.0+cp6*pick_x;
-    var cp0cx1,cp3cx1;
-    var cp1cy_cp21=cp1cy_cp20+cp1;
-    var cp4cy_cp51=cp4cy_cp50+cp4;
-    var cp7cy_11=cp7cy_10+cp7;
-    var cw0=cp1+cp1;
-    var cw7=cp7+cp7;
-    var cw4=cp4+cp4;
-    for(var iy=this._size_ref.h-1;iy>=0;iy--){
-      cp0cx0=cp1cy_cp20;
-      cp3cx0=cp4cy_cp50;
-      cp0cx1=cp1cy_cp21;
-      cp3cx1=cp4cy_cp51;
-      m0=1.0/(cp7cy_10);
-      d0=-cp6/(cp7cy_10*(cp7cy_10+cp6));
-      m1=1.0/(cp7cy_11);
-      d1=-cp6/(cp7cy_11*(cp7cy_11+cp6));
-      var n=patt_w*2*2-1;
-      var ix;
-      for(ix=patt_w*2-1;ix>=0;ix--){
-        //[n,0]
-        x=rgb_px[n]=toInt(cp0cx0*m0);
-        y=rgb_py[n]=toInt(cp3cx0*m0);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[n]=0;}else if(x>=img_x){rgb_px[n]=img_x-1;}
-          if(y<0){rgb_py[n]=0;}else if(y>=img_y){rgb_py[n]=img_y-1;}
-        }
-        cp0cx0+=cp0;
-        cp3cx0+=cp3;
-        m0+=d0;
-        n--;
-        //[n,1]
-        x=rgb_px[n]=toInt(cp0cx1*m1);
-        y=rgb_py[n]=toInt(cp3cx1*m1);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[n]=0;}else if(x>=img_x){rgb_px[n]=img_x-1;}
-          if(y<0){rgb_py[n]=0;}else if(y>=img_y){rgb_py[n]=img_y-1;}
-        }
-        cp0cx1+=cp0;
-        cp3cx1+=cp3;
-        m1+=d1;
-        n--;
-      }
-      cp7cy_10+=cw7;
-      cp7cy_11+=cw7;
-      cp1cy_cp20+=cw0;
-      cp4cy_cp50+=cw4;
-      cp1cy_cp21+=cw0;
-      cp4cy_cp51+=cw4;
-      reader.getPixelSet(rgb_px, rgb_py,patt_w*4, rgb_tmp);
-      for(ix=patt_w-1;ix>=0;ix--){
-        var idx=ix*12;//3*2*2
-        var r=(rgb_tmp[idx+0]+rgb_tmp[idx+3]+rgb_tmp[idx+6]+rgb_tmp[idx+ 9])/4;
-        var g=(rgb_tmp[idx+1]+rgb_tmp[idx+4]+rgb_tmp[idx+7]+rgb_tmp[idx+10])/4;
-        var b=(rgb_tmp[idx+2]+rgb_tmp[idx+5]+rgb_tmp[idx+8]+rgb_tmp[idx+11])/4;
-        o_patt[p]=(r<<16)|(g<<8)|((b&0xff));
-        p++;
-      }
-    }
-    return;
-  }
-})
-/*
-* PROJECT: NyARToolkitAS3
-* --------------------------------------------------------------------------------
-* This work is based on the original ARToolKit developed by
-*   Hirokazu Kato
-*   Mark Billinghurst
-*   HITLab, University of Washington, Seattle
-* http://www.hitl.washington.edu/artoolkit/
-*
-* The NyARToolkitAS3 is AS3 edition ARToolKit class library.
-* Copyright (C)2010 Ryo Iizuka
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*
-* For further information please contact.
-*  http://nyatla.jp/nyatoolkit/
-*  <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
-*
-*/
-
-
-
-
-/**
- * 4x4
- *
- */
-NyARPickFromRaster_4x = ASKlass('NyARPickFromRaster_4x', IpickFromRaster_Impl,
-{
-  _size_ref : null,
-  _lt_ref : null,
-  NyARPickFromRaster_4x : function(i_lt,i_source_size)
-  {
-    this._lt_ref=i_lt;
-    this._size_ref=i_source_size;
-    this._rgb_temp=new IntVector(4*4*3);
-    this._rgb_px=new IntVector(4*4);
-    this._rgb_py=new IntVector(4*4);
-    return;
-  },
-  _rgb_temp : null,
-  _rgb_px : null,
-  _rgb_py : null,
-  pickFromRaster : function(i_cpara, image, o_patt)
-  {
-    var x,y;
-    var d,m;
-    var cp6cx,cp0cx,cp3cx;
-    var rgb_px=this._rgb_px;
-    var rgb_py=this._rgb_py;
-    var r,g,b;
-    //遠近法のパラメータを計算
-    var img_x = image.getWidth();
-    var img_y = image.getHeight();
-    var rgb_tmp = this._rgb_temp;
-    var cp0=i_cpara[0];
-    var cp3=i_cpara[3];
-    var cp6=i_cpara[6];
-    var cp1=i_cpara[1];
-    var cp2=i_cpara[2];
-    var cp4=i_cpara[4];
-    var cp5=i_cpara[5];
-    var cp7=i_cpara[7];
-    var pick_lt_x=this._lt_ref.x;
-    //ピクセルリーダーを取得
-    var reader=image.getRgbPixelReader();
-    var p=0;
-    var py=this._lt_ref.y;
-    for(var iy=this._size_ref.h-1;iy>=0;iy--,py+=4){
-      var cp1cy_cp2_0=cp1*py+cp2;
-      var cp4cy_cp5_0=cp4*py+cp5;
-      var cp7cy_1_0  =cp7*py+1.0;
-      var cp1cy_cp2_1=cp1cy_cp2_0+cp1;
-      var cp1cy_cp2_2=cp1cy_cp2_1+cp1;
-      var cp1cy_cp2_3=cp1cy_cp2_2+cp1;
-      var cp4cy_cp5_1=cp4cy_cp5_0+cp4;
-      var cp4cy_cp5_2=cp4cy_cp5_1+cp4;
-      var cp4cy_cp5_3=cp4cy_cp5_2+cp4;
-      var px=pick_lt_x;
-      //解像度分の点を取る。
-      for(var ix=this._size_ref.w-1;ix>=0;ix--,px+=4){
-        cp6cx=cp6*px;
-        cp0cx=cp0*px;
-        cp3cx=cp3*px;
-        cp6cx+=cp7cy_1_0;
-        m=1/cp6cx;
-        d=-cp7/((cp6cx+cp7)*cp6cx);
-        //1ピクセルを作成[0,0]
-        x=rgb_px[0]=toInt((cp0cx+cp1cy_cp2_0)*m);
-        y=rgb_py[0]=toInt((cp3cx+cp4cy_cp5_0)*m);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[0]=0;} else if(x>=img_x){rgb_px[0]=img_x-1;}
-          if(y<0){rgb_py[0]=0;} else if(y>=img_y){rgb_py[0]=img_y-1;}
-        }
-        //1ピクセルを作成[0,1]
-        m+=d;
-        x=rgb_px[4]=toInt((cp0cx+cp1cy_cp2_1)*m);
-        y=rgb_py[4]=toInt((cp3cx+cp4cy_cp5_1)*m);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[4]=0;}else if(x>=img_x){rgb_px[4]=img_x-1;}
-          if(y<0){rgb_py[4]=0;}else if(y>=img_y){rgb_py[4]=img_y-1;}
-        }
-        //1ピクセルを作成[0,2]
-        m+=d;
-        x=rgb_px[8]=toInt((cp0cx+cp1cy_cp2_2)*m);
-        y=rgb_py[8]=toInt((cp3cx+cp4cy_cp5_2)*m);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[8]=0;}else if(x>=img_x){rgb_px[8]=img_x-1;}
-          if(y<0){rgb_py[8]=0;}else if(y>=img_y){rgb_py[8]=img_y-1;}
-        }
-        //1ピクセルを作成[0,3]
-        m+=d;
-        x=rgb_px[12]=toInt((cp0cx+cp1cy_cp2_3)*m);
-        y=rgb_py[12]=toInt((cp3cx+cp4cy_cp5_3)*m);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[12]=0;}else if(x>=img_x){rgb_px[12]=img_x-1;}
-          if(y<0){rgb_py[12]=0;}else if(y>=img_y){rgb_py[12]=img_y-1;}
-        }
-        cp6cx+=cp6;
-        cp0cx+=cp0;
-        cp3cx+=cp3;
-        m=1/cp6cx;
-        d=-cp7/((cp6cx+cp7)*cp6cx);
-        //1ピクセルを作成[1,0]
-        x=rgb_px[1]=toInt((cp0cx+cp1cy_cp2_0)*m);
-        y=rgb_py[1]=toInt((cp3cx+cp4cy_cp5_0)*m);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[1]=0;}else if(x>=img_x){rgb_px[1]=img_x-1;}
-          if(y<0){rgb_py[1]=0;}else if(y>=img_y){rgb_py[1]=img_y-1;}
-        }
-        //1ピクセルを作成[1,1]
-        m+=d;
-        x=rgb_px[5]=toInt((cp0cx+cp1cy_cp2_1)*m);
-        y=rgb_py[5]=toInt((cp3cx+cp4cy_cp5_1)*m);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[5]=0;}else if(x>=img_x){rgb_px[5]=img_x-1;}
-          if(y<0){rgb_py[5]=0;}else if(y>=img_y){rgb_py[5]=img_y-1;}
-        }
-        //1ピクセルを作成[1,2]
-        m+=d;
-        x=rgb_px[9]=toInt((cp0cx+cp1cy_cp2_2)*m);
-        y=rgb_py[9]=toInt((cp3cx+cp4cy_cp5_2)*m);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[9]=0;}else if(x>=img_x){rgb_px[9]=img_x-1;}
-          if(y<0){rgb_py[9]=0;}else if(y>=img_y){rgb_py[9]=img_y-1;}
-        }
-        //1ピクセルを作成[1,3]
-        m+=d;
-        x=rgb_px[13]=toInt((cp0cx+cp1cy_cp2_3)*m);
-        y=rgb_py[13]=toInt((cp3cx+cp4cy_cp5_3)*m);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[13]=0;}else if(x>=img_x){rgb_px[13]=img_x-1;}
-          if(y<0){rgb_py[13]=0;}else if(y>=img_y){rgb_py[13]=img_y-1;}
-        }
-        cp6cx+=cp6;
-        cp0cx+=cp0;
-        cp3cx+=cp3;
-        m=1/cp6cx;
-        d=-cp7/((cp6cx+cp7)*cp6cx);
-        //1ピクセルを作成[2,0]
-        x=rgb_px[2]=toInt((cp0cx+cp1cy_cp2_0)*m);
-        y=rgb_py[2]=toInt((cp3cx+cp4cy_cp5_0)*m);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[2]=0;}else if(x>=img_x){rgb_px[2]=img_x-1;}
-          if(y<0){rgb_py[2]=0;}else if(y>=img_y){rgb_py[2]=img_y-1;}
-        }
-        //1ピクセルを作成[2,1]
-        m+=d;
-        x=rgb_px[6]=toInt((cp0cx+cp1cy_cp2_1)*m);
-        y=rgb_py[6]=toInt((cp3cx+cp4cy_cp5_1)*m);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[6]=0;}else if(x>=img_x){rgb_px[6]=img_x-1;}
-          if(y<0){rgb_py[6]=0;}else if(y>=img_y){rgb_py[6]=img_y-1;}
-        }
-        //1ピクセルを作成[2,2]
-        m+=d;
-        x=rgb_px[10]=toInt((cp0cx+cp1cy_cp2_2)*m);
-        y=rgb_py[10]=toInt((cp3cx+cp4cy_cp5_2)*m);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[10]=0;}else if(x>=img_x){rgb_px[10]=img_x-1;}
-          if(y<0){rgb_py[10]=0;}else if(y>=img_y){rgb_py[10]=img_y-1;}
-        }
-        //1ピクセルを作成[2,3](ここ計算ずれします。)
-        m+=d;
-        x=rgb_px[14]=toInt((cp0cx+cp1cy_cp2_3)*m);
-        y=rgb_py[14]=toInt((cp3cx+cp4cy_cp5_3)*m);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[14]=0;}else if(x>=img_x){rgb_px[14]=img_x-1;}
-          if(y<0){rgb_py[14]=0;}else if(y>=img_y){rgb_py[14]=img_y-1;}
-        }
-        cp6cx+=cp6;
-        cp0cx+=cp0;
-        cp3cx+=cp3;
-        m=1/cp6cx;
-        d=-cp7/((cp6cx+cp7)*cp6cx);
-        //1ピクセルを作成[3,0]
-        x=rgb_px[3]=toInt((cp0cx+cp1cy_cp2_0)*m);
-        y=rgb_py[3]=toInt((cp3cx+cp4cy_cp5_0)*m);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[3]=0;}else if(x>=img_x){rgb_px[3]=img_x-1;}
-          if(y<0){rgb_py[3]=0;}else if(y>=img_y){rgb_py[3]=img_y-1;}
-        }
-        //1ピクセルを作成[3,1]
-        m+=d;
-        x=rgb_px[7]=toInt((cp0cx+cp1cy_cp2_1)*m);
-        y=rgb_py[7]=toInt((cp3cx+cp4cy_cp5_1)*m);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[7]=0;}else if(x>=img_x){rgb_px[7]=img_x-1;}
-          if(y<0){rgb_py[7]=0;}else if(y>=img_y){rgb_py[7]=img_y-1;}
-        }
-        //1ピクセルを作成[3,2]
-        m+=d;
-        x=rgb_px[11]=toInt((cp0cx+cp1cy_cp2_2)*m);
-        y=rgb_py[11]=toInt((cp3cx+cp4cy_cp5_2)*m);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[11]=0;}else if(x>=img_x){rgb_px[11]=img_x-1;}
-          if(y<0){rgb_py[11]=0;}else if(y>=img_y){rgb_py[11]=img_y-1;}
-        }
-        //1ピクセルを作成[3,3]
-        m+=d;
-        x=rgb_px[15]=toInt((cp0cx+cp1cy_cp2_3)*m);
-        y=rgb_py[15]=toInt((cp3cx+cp4cy_cp5_3)*m);
-        if(x<0||x>=img_x||y<0||y>=img_y){
-          if(x<0){rgb_px[15]=0;}else if(x>=img_x){rgb_px[15]=img_x-1;}
-          if(y<0){rgb_py[15]=0;}else if(y>=img_y){rgb_py[15]=img_y-1;}
-        }
-        reader.getPixelSet(rgb_px, rgb_py,4*4, rgb_tmp);
-        r=(rgb_tmp[ 0]+rgb_tmp[ 3]+rgb_tmp[ 6]+rgb_tmp[ 9]+rgb_tmp[12]+rgb_tmp[15]+rgb_tmp[18]+rgb_tmp[21]+rgb_tmp[24]+rgb_tmp[27]+rgb_tmp[30]+rgb_tmp[33]+rgb_tmp[36]+rgb_tmp[39]+rgb_tmp[42]+rgb_tmp[45])/16;
-        g=(rgb_tmp[ 1]+rgb_tmp[ 4]+rgb_tmp[ 7]+rgb_tmp[10]+rgb_tmp[13]+rgb_tmp[16]+rgb_tmp[19]+rgb_tmp[22]+rgb_tmp[25]+rgb_tmp[28]+rgb_tmp[31]+rgb_tmp[34]+rgb_tmp[37]+rgb_tmp[40]+rgb_tmp[43]+rgb_tmp[46])/16;
-        b=(rgb_tmp[ 2]+rgb_tmp[ 5]+rgb_tmp[ 8]+rgb_tmp[11]+rgb_tmp[14]+rgb_tmp[17]+rgb_tmp[20]+rgb_tmp[23]+rgb_tmp[26]+rgb_tmp[29]+rgb_tmp[32]+rgb_tmp[35]+rgb_tmp[38]+rgb_tmp[41]+rgb_tmp[44]+rgb_tmp[47])/16;
-        o_patt[p]=((r&0xff)<<16)|((g&0xff)<<8)|((b&0xff));
-        p++;
-      }
-    }
-    return;
-  }
-})
-/*
-* PROJECT: NyARToolkitAS3
-* --------------------------------------------------------------------------------
-* This work is based on the original ARToolKit developed by
-*   Hirokazu Kato
-*   Mark Billinghurst
-*   HITLab, University of Washington, Seattle
-* http://www.hitl.washington.edu/artoolkit/
-*
-* The NyARToolkitAS3 is AS3 edition ARToolKit class library.
-* Copyright (C)2010 Ryo Iizuka
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*
-* For further information please contact.
-*  http://nyatla.jp/nyatoolkit/
-*  <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
-*
-*/
-
-
-
-
-/**
- * 汎用ピックアップ関数
- *
- */
-NyARPickFromRaster_N = ASKlass('NyARPickFromRaster_N', IpickFromRaster_Impl,
-{
-  _resolution : 0,
-  _size_ref : null,
-  _lt_ref : null,
-  NyARPickFromRaster_N : function(i_lt,i_resolution,i_source_size)
-  {
-    this._lt_ref=i_lt;
-    this._resolution=i_resolution;
-    this._size_ref=i_source_size;
-    this._rgb_temp=new IntVector(i_resolution*i_resolution*3);
-    this._rgb_px=new IntVector(i_resolution*i_resolution);
-    this._rgb_py=new IntVector(i_resolution*i_resolution);
-    this._cp1cy_cp2=new FloatVector(i_resolution);
-    this._cp4cy_cp5=new FloatVector(i_resolution);
-    this._cp7cy_1=new FloatVector(i_resolution);
-    return;
-  },
-  _rgb_temp : null,
-  _rgb_px : null,
-  _rgb_py : null,
-  _cp1cy_cp2 : null,
-  _cp4cy_cp5 : null,
-  _cp7cy_1 : null,
-  pickFromRaster : function(i_cpara,image,o_patt)
-  {
-    var i2x,i2y;//プライム変数
-    var x,y;
-    var w;
-    var r,g,b;
-    var resolution=this._resolution;
-    var res_pix=resolution*resolution;
-    var img_x = image.getWidth();
-    var img_y = image.getHeight();
-    var rgb_tmp = this._rgb_temp;
-    var rgb_px=this._rgb_px;
-    var rgb_py=this._rgb_py;
-    var cp1cy_cp2=this._cp1cy_cp2;
-    var cp4cy_cp5=this._cp4cy_cp5;
-    var cp7cy_1=this._cp7cy_1;
-    var cp0=i_cpara[0];
-    var cp3=i_cpara[3];
-    var cp6=i_cpara[6];
-    var cp1=i_cpara[1];
-    var cp2=i_cpara[2];
-    var cp4=i_cpara[4];
-    var cp5=i_cpara[5];
-    var cp7=i_cpara[7];
-    var pick_y=this._lt_ref.y;
-    var pick_x=this._lt_ref.x;
-    //ピクセルリーダーを取得
-    var reader=image.getRgbPixelReader();
-    var p=0;
-    for(var iy=0;iy<this._size_ref.h*resolution;iy+=resolution){
-      w=pick_y+iy;
-      cp1cy_cp2[0]=cp1*w+cp2;
-      cp4cy_cp5[0]=cp4*w+cp5;
-      cp7cy_1[0]=cp7*w+1.0;
-      for(i2y=1;i2y<resolution;i2y++){
-        cp1cy_cp2[i2y]=cp1cy_cp2[i2y-1]+cp1;
-        cp4cy_cp5[i2y]=cp4cy_cp5[i2y-1]+cp4;
-        cp7cy_1[i2y]=cp7cy_1[i2y-1]+cp7;
-      }
-      //解像度分の点を取る。
-      for(var ix=0;ix<this._size_ref.w*resolution;ix+=resolution){
-        var n=0;
-        w=pick_x+ix;
-        for(i2y=resolution-1;i2y>=0;i2y--){
-          var cp0cx=cp0*w+cp1cy_cp2[i2y];
-          var cp6cx=cp6*w+cp7cy_1[i2y];
-          var cp3cx=cp3*w+cp4cy_cp5[i2y];
-          var m=1/(cp6cx);
-          var d=-cp6/(cp6cx*(cp6cx+cp6));
-          var m2=cp0cx*m;
-          var m3=cp3cx*m;
-          var d2=cp0cx*d+cp0*(m+d);
-          var d3=cp3cx*d+cp3*(m+d);
-          for(i2x=resolution-1;i2x>=0;i2x--){
-            //1ピクセルを作成
-            x=rgb_px[n]=toInt(m2);
-            y=rgb_py[n]=toInt(m3);
-            if(x<0||x>=img_x||y<0||y>=img_y){
-              if(x<0){rgb_px[n]=0;}else if(x>=img_x){rgb_px[n]=img_x-1;}
-              if(y<0){rgb_py[n]=0;}else if(y>=img_y){rgb_py[n]=img_y-1;}
-            }
-            n++;
-            m2+=d2;
-            m3+=d3;
-          }
-        }
-        reader.getPixelSet(rgb_px, rgb_py,res_pix, rgb_tmp);
-        r=g=b=0;
-        for(var i=res_pix*3-1;i>0;){
-          b+=rgb_tmp[i--];
-          g+=rgb_tmp[i--];
-          r+=rgb_tmp[i--];
-        }
-        r/=res_pix;
-        g/=res_pix;
-        b/=res_pix;
-        o_patt[p]=((r&0xff)<<16)|((g&0xff)<<8)|((b&0xff));
-        p++;
-      }
-    }
-    return;
-  }
-})
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * JSARToolkit
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- *   Hirokazu Kato
- *   Mark Billinghurst
- *   HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * And the NyARToolkitAS3 ARToolKit class library.
- *   Copyright (C)2010 Ryo Iizuka
- *
- * JSARToolkit is a JavaScript port of NyARToolkitAS3.
- *   Copyright (C)2010 Ilmari Heikkinen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  ilmari.heikkinen@gmail.com
- *
- */
-NyARCustomSingleDetectMarker = ASKlass('NyARCustomSingleDetectMarker',
-{
-  _is_continue : false,
-  _square_detect : null,
-  _transmat : null,
-  //画処理用
-  _bin_raster : null,
-  _tobin_filter : null,
-  _detect_cb : null,
-  _offset : null,
-  NyARCustomSingleDetectMarker : function()
-  {
-    return;
-  }
-  ,initInstance : function(
-    i_patt_inst,
-    i_sqdetect_inst,
-    i_transmat_inst,
-    i_filter,
-    i_ref_param,
-    i_ref_code,
-    i_marker_width)
-  {
-    var scr_size=i_ref_param.getScreenSize();
-    // 解析オブジェクトを作る
-    this._square_detect = i_sqdetect_inst;
-    this._transmat = i_transmat_inst;
-    this._tobin_filter=i_filter;
-    //２値画像バッファを作る
-    this._bin_raster=new NyARBinRaster(scr_size.w,scr_size.h);
-    //_detect_cb
-    this._detect_cb=new DetectSquareCB_3(i_patt_inst,i_ref_code,i_ref_param);
-    //オフセットを作成
-    this._offset=new NyARRectOffset();
-    this._offset.setSquare(i_marker_width);
-    return;
-  }
-  /**
-   * i_imageにマーカー検出処理を実行し、結果を記録します。
-   *
-   * @param i_raster
-   * マーカーを検出するイメージを指定します。イメージサイズは、カメラパラメータ
-   * と一致していなければなりません。
-   * @return マーカーが検出できたかを真偽値で返します。
-   * @throws NyARException
-   */
-  ,detectMarkerLiteB : function(i_raster)    {
-    //サイズチェック
-    if(!this._bin_raster.getSize().isEqualSize_NyARIntSize(i_raster.getSize())){
-      throw new NyARException();
-    }
-    //ラスタを２値イメージに変換する.
-    this._tobin_filter.doFilter(i_raster,this._bin_raster);
-    //コールバックハンドラの準備
-    this._detect_cb.init(i_raster);
-    //矩形を探す(戻り値はコールバック関数で受け取る。)
-    this._square_detect.detectMarkerCB(this._bin_raster,_detect_cb);
-    if(this._detect_cb.confidence==0){
-      return false;
-    }
-    return true;
-  }
-  /**
-   * 検出したマーカーの変換行列を計算して、o_resultへ値を返します。
-   * 直前に実行したdetectMarkerLiteが成功していないと使えません。
-   *
-   * @param o_result
-   * 変換行列を受け取るオブジェクトを指定します。
-   * @throws NyARException
-   */
-  ,getTransmationMatrix : function(o_result)
-  {
-    // 一番一致したマーカーの位置とかその辺を計算
-    if (this._is_continue) {
-      this._transmat.transMatContinue(this._detect_cb.square,this._offset, o_result);
-    } else {
-      this._transmat.transMat(this._detect_cb.square,this._offset, o_result);
-    }
-    return;
-  }
-  /**
-   * 現在の矩形を返します。
-   * @return
-   */
-  ,refSquare : function()
-  {
-    return this._detect_cb.square;
-  }
-  /**
-   * 検出したマーカーの一致度を返します。
-   *
-   * @return マーカーの一致度を返します。0～1までの値をとります。 一致度が低い場合には、誤認識の可能性が高くなります。
-   * @throws NyARException
-   */
-  ,getConfidence : function()
-  {
-    return this._detect_cb.confidence;
-  }
-  /**
-   * getTransmationMatrixの計算モードを設定します。 初期値はTRUEです。
-   *
-   * @param i_is_continue
-   * TRUEなら、transMatCont互換の計算をします。 FALSEなら、transMat互換の計算をします。
-   */
-  ,setContinueMode : function(i_is_continue)
-  {
-    this._is_continue = i_is_continue;
-  }
-})
-
-
-
-
-
-
-
-
-
-
-/**
- * detectMarkerのコールバック関数
- */
-DetectSquareCB_3 = ASKlass('DetectSquareCB', NyARSquareContourDetector_IDetectMarkerCallback,
-{
-  //公開プロパティ
-  confidence : 0,
-  square : new NyARSquare(),
-  //参照インスタンス
-  _ref_raster : null,
-  //所有インスタンス
-  _inst_patt : null,
-  _deviation_data : null,
-  _match_patt : null,
-  __detectMarkerLite_mr : new NyARMatchPattResult(),
-  _coordline : null,
-  DetectSquareCB : function(i_inst_patt,i_ref_code,i_param)
-  {
-    this._inst_patt=i_inst_patt;
-    this._deviation_data=new NyARMatchPattDeviationColorData(i_ref_code.getWidth(),i_ref_code.getHeight());
-    this._coordline=new NyARCoord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor());
-    this._match_patt=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code);
-    return;
-  },
-  __tmp_vertex : NyARIntPoint2d.createArray(4),
-  /**
-  * 矩形が見付かるたびに呼び出されます。
-  * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。
-  */
-  onSquareDetect : function(i_sender,i_coordx,i_coordy,i_coor_num,i_vertex_index)
-  {
-    var i;
-    var mr=this.__detectMarkerLite_mr;
-    //輪郭座標から頂点リストに変換
-    var vertex=this.__tmp_vertex;
-    vertex[0].x=i_coordx[i_vertex_index[0]];
-    vertex[0].y=i_coordy[i_vertex_index[0]];
-    vertex[1].x=i_coordx[i_vertex_index[1]];
-    vertex[1].y=i_coordy[i_vertex_index[1]];
-    vertex[2].x=i_coordx[i_vertex_index[2]];
-    vertex[2].y=i_coordy[i_vertex_index[2]];
-    vertex[3].x=i_coordx[i_vertex_index[3]];
-    vertex[3].y=i_coordy[i_vertex_index[3]];
-    //画像を取得
-    if (!this._inst_patt.pickFromRaster(this._ref_raster,vertex)){
-      return;
-    }
-    //取得パターンをカラー差分データに変換して評価する。
-    this._deviation_data.setRaster(this._inst_patt);
-    if(!this._match_patt.evaluate(this._deviation_data,mr)){
-      return;
-    }
-    //現在の一致率より低ければ終了
-    if (this.confidence > mr.confidence){
-      return;
-    }
-    //一致率の高い矩形があれば、方位を考慮して頂点情報を作成
-    var sq=this.square;
-    this.confidence = mr.confidence;
-    //directionを考慮して、squareを更新する。
-    for(i=0;i<4;i++){
-      var idx=(i+4 - mr.direction) % 4;
-      this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coordx,i_coordy,i_coor_num,sq.line[i]);
-    }
-    for (i = 0; i < 4; i++) {
-      //直線同士の交点計算
-      if(!NyARLinear.crossPos(sq.line[i],sq.line[(i + 3) % 4],sq.sqvertex[i])){
-        throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK
-      }
-    }
-  }
-  ,init : function(i_raster)
-  {
-    this.confidence=0;
-    this._ref_raster=i_raster;
-  }
-})
-
-
-
-
-
-
-
-
-
-
-/**
- * 複数のマーカーを検出し、それぞれに最も一致するARコードを、コンストラクタで登録したARコードから 探すクラスです。最大300個を認識しますが、ゴミラベルを認識したりするので100個程度が限界です。
- *
- */
-NyARDetectMarker = ASKlass('NyARDetectMarker',
-{
-  _detect_cb : null,
-  AR_SQUARE_MAX : 300,
-  _is_continue : false,
-  _square_detect : null,
-  _transmat : null,
-  _offset : null,
-  /**
-   * 複数のマーカーを検出し、最も一致するARCodeをi_codeから検索するオブジェクトを作ります。
-   *
-   * @param i_param
-   * カメラパラメータを指定します。
-   * @param i_code
-   * 検出するマーカーのARCode配列を指定します。
-   * 配列要素のインデックス番号が、そのままgetARCodeIndex関数で得られるARCodeインデックスになります。
-   * 例えば、要素[1]のARCodeに一致したマーカーである場合は、getARCodeIndexは1を返します。
-   * @param i_marker_width
-   * i_codeのマーカーサイズをミリメートルで指定した配列を指定します。 先頭からi_number_of_code個の要素には、有効な値を指定する必要があります。
-   * @param i_number_of_code
-   * i_codeに含まれる、ARCodeの数を指定します。
-   * @param i_input_raster_type
-   * 入力ラスタのピクセルタイプを指定します。この値は、INyARBufferReaderインタフェイスのgetBufferTypeの戻り値を指定します。
-   * @throws NyARException
-   */
-  NyARDetectMarker : function(i_param, i_code, i_marker_width, i_number_of_code, i_input_raster_type)
-  {
-    this.initInstance(i_param,i_code,i_marker_width,i_number_of_code,i_input_raster_type);
-    return;
-  }
-  ,initInstance : function(
-    i_ref_param,
-    i_ref_code,
-    i_marker_width,
-    i_number_of_code,
-    i_input_raster_type)
-  {
-    var scr_size=i_ref_param.getScreenSize();
-    // 解析オブジェクトを作る
-    var cw = i_ref_code[0].getWidth();
-    var ch = i_ref_code[0].getHeight();
-    //detectMarkerのコールバック関数
-    this._detect_cb=new NyARDetectSquareCB(
-      new NyARColorPatt_Perspective_O2(cw, ch,4,25),
-      i_ref_code,i_number_of_code,i_ref_param);
-    this._transmat = new NyARTransMat(i_ref_param);
-    //NyARToolkitプロファイル
-    this._square_detect =new NyARSquareContourDetector_Rle(i_ref_param.getScreenSize());
-    this._tobin_filter=new NyARRasterFilter_ARToolkitThreshold(100,i_input_raster_type);
-    //実サイズ保存
-    this._offset = NyARRectOffset.createArray(i_number_of_code);
-    for(var i=0;i<i_number_of_code;i++){
-      this._offset[i].setSquare(i_marker_width[i]);
-    }
-    //２値画像バッファを作る
-    this._bin_raster=new NyARBinRaster(scr_size.w,scr_size.h);
-    return;
-  },
-  _bin_raster : null,
-  _tobin_filter : null,
-  /**
-   * i_imageにマーカー検出処理を実行し、結果を記録します。
-   *
-   * @param i_raster
-   * マーカーを検出するイメージを指定します。
-   * @param i_thresh
-   * 検出閾値を指定します。0～255の範囲で指定してください。 通常は100～130くらいを指定します。
-   * @return 見つかったマーカーの数を返します。 マーカーが見つからない場合は0を返します。
-   * @throws NyARException
-   */
-  detectMarkerLite : function(i_raster,i_threshold)
-  {
-    // サイズチェック
-    if (!this._bin_raster.getSize().isEqualSize_NyARIntSize(i_raster.getSize())) {
-      throw new NyARException();
-    }
-    // ラスタを２値イメージに変換する.
-    (NyARRasterFilter_ARToolkitThreshold(this._tobin_filter)).setThreshold(i_threshold);
-    this._tobin_filter.doFilter(i_raster, this._bin_raster);
-    //detect
-    this._detect_cb.init(i_raster);
-    this._square_detect.detectMarkerCB(this._bin_raster,this._detect_cb);
-    //見付かった数を返す。
-    return this._detect_cb.result_stack.getLength();
-  }
-  /**
-   * i_indexのマーカーに対する変換行列を計算し、結果値をo_resultへ格納します。 直前に実行したdetectMarkerLiteが成功していないと使えません。
-   *
-   * @param i_index
-   * マーカーのインデックス番号を指定します。 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。
-   * @param o_result
-   * 結果値を受け取るオブジェクトを指定してください。
-   * @throws NyARException
-   */
-  ,getTransmationMatrix : function(i_index, o_result)
-  {
-    var result = this._detect_cb.result_stack.getItem(i_index);
-    // 一番一致したマーカーの位置とかその辺を計算
-    if (_is_continue) {
-      _transmat.transMatContinue(result.square, this._offset[result.arcode_id], o_result);
-    } else {
-      _transmat.transMat(result.square, this._offset[result.arcode_id], o_result);
-    }
-    return;
-  }
-  /**
-   * i_indexのマーカーの一致度を返します。
-   *
-   * @param i_index
-   * マーカーのインデックス番号を指定します。 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。
-   * @return マーカーの一致度を返します。0～1までの値をとります。 一致度が低い場合には、誤認識の可能性が高くなります。
-   * @throws NyARException
-   */
-  ,getConfidence : function(i_index)
-  {
-    return this._detect_cb.result_stack.getItem(i_index).confidence;
-  }
-  /**
-   * i_indexのマーカーのARCodeインデックスを返します。
-   *
-   * @param i_index
-   * マーカーのインデックス番号を指定します。 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。
-   * @return
-   */
-  ,getARCodeIndex : function(i_index)
-  {
-    return this._detect_cb.result_stack.getItem(i_index).arcode_id;
-  }
-  /**
-   * getTransmationMatrixの計算モードを設定します。
-   *
-   * @param i_is_continue
-   * TRUEなら、transMatContinueを使用します。 FALSEなら、transMatを使用します。
-   */
-  ,setContinueMode : function(i_is_continue)
-  {
-    this._is_continue = i_is_continue;
-  }
-})
-
-NyARDetectMarkerResult = ASKlass('NyARDetectMarkerResult',
-{
-  arcode_id : 0,
-  confidence : 0,
-  square : new NyARSquare()
-})
-
-NyARDetectMarkerResultStack = ASKlass('NyARDetectMarkerResultStack ', NyARObjectStack,
-{
-  NyARDetectMarkerResultStack : function(i_length)
-  {
-    NyARObjectStack.initialize.call(this, i_length);
-  }
-  ,createArray : function(i_length)
-  {
-    var ret= new Array(i_length);
-    for (var i =0; i < i_length; i++){
-      ret[i] = new NyARDetectMarkerResult();
-    }
-    return (ret);
-  }
-})
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-NyARDetectSquareCB = ASKlass('NyARDetectSquareCB ', NyARSquareContourDetector_IDetectMarkerCallback,
-{
-  //公開プロパティ
-  result_stack : new NyARDetectMarkerResultStack(NyARDetectMarker.AR_SQUARE_MAX),
-  //参照インスタンス
-  _ref_raster : null,
-  //所有インスタンス
-  _inst_patt : null,
-  _deviation_data : null,
-  _match_patt : null,
-  __detectMarkerLite_mr : new NyARMatchPattResult(),
-  _coordline : null,
-  NyARDetectSquareCB : function(i_inst_patt, i_ref_code, i_num_of_code, i_param)
-  {
-    var cw = i_ref_code[0].getWidth();
-    var ch = i_ref_code[0].getHeight();
-    this._inst_patt=i_inst_patt;
-    this._coordline=new NyARCoord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor());
-    this._deviation_data=new NyARMatchPattDeviationColorData(cw,ch);
-    //NyARMatchPatt_Color_WITHOUT_PCA[]の作成
-    this._match_patt=new Array(i_num_of_code);
-    this._match_patt[0]=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code[0]);
-    for (var i = 1; i < i_num_of_code; i++){
-      //解像度チェック
-      if (cw != i_ref_code[i].getWidth() || ch != i_ref_code[i].getHeight()) {
-        throw new NyARException();
-      }
-      this._match_patt[i]=new NyARMatchPatt_Color_WITHOUT_PCA(i_ref_code[i]);
-    }
-    return;
-  },
-  __tmp_vertex : NyARIntPoint2d.createArray(4),
-  /**
-   * 矩形が見付かるたびに呼び出されます。
-   * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。
-   */
-  onSquareDetect : function(i_sender,i_coordx,i_coordy,i_coor_num ,i_vertex_index)
-  {
-    var mr=this.__detectMarkerLite_mr;
-    //輪郭座標から頂点リストに変換
-    var vertex=this.__tmp_vertex;
-    vertex[0].x=i_coordx[i_vertex_index[0]];
-    vertex[0].y=i_coordy[i_vertex_index[0]];
-    vertex[1].x=i_coordx[i_vertex_index[1]];
-    vertex[1].y=i_coordy[i_vertex_index[1]];
-    vertex[2].x=i_coordx[i_vertex_index[2]];
-    vertex[2].y=i_coordy[i_vertex_index[2]];
-    vertex[3].x=i_coordx[i_vertex_index[3]];
-    vertex[3].y=i_coordy[i_vertex_index[3]];
-    //画像を取得
-    if (!this._inst_patt.pickFromRaster(this._ref_raster,vertex)){
-      return;
-    }
-    //取得パターンをカラー差分データに変換して評価する。
-    this._deviation_data.setRaster(this._inst_patt);
-    //最も一致するパターンを割り当てる。
-    var square_index,direction;
-    var confidence;
-    this._match_patt[0].evaluate(this._deviation_data,mr);
-    square_index=0;
-    direction=mr.direction;
-    confidence=mr.confidence;
-    //2番目以降
-    var i;
-    for(i=1;i<this._match_patt.length;i++){
-      this._match_patt[i].evaluate(this._deviation_data,mr);
-      if (confidence > mr.confidence) {
-        continue;
-      }
-      // もっと一致するマーカーがあったぽい
-      square_index = i;
-      direction = mr.direction;
-      confidence = mr.confidence;
-    }
-    //最も一致したマーカ情報を、この矩形の情報として記録する。
-    var result = this.result_stack.prePush();
-    result.arcode_id = square_index;
-    result.confidence = confidence;
-    var sq=result.square;
-    //directionを考慮して、squareを更新する。
-    for(i=0;i<4;i++){
-      var idx=(i+4 - direction) % 4;
-      this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coordx,i_coordy,i_coor_num,sq.line[i]);
-    }
-    for (i = 0; i < 4; i++) {
-      //直線同士の交点計算
-      if(!NyARLinear.crossPos(sq.line[i],sq.line[(i + 3) % 4],sq.sqvertex[i])){
-        throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK
-      }
-    }
-  }
-  ,init : function(i_raster)
-  {
-    this._ref_raster=i_raster;
-    this.result_stack.clear();
-  }
-})
-
-
-
-
-
-
-
-
-
-
-/**
- * 画像からARCodeに最も一致するマーカーを1個検出し、その変換行列を計算するクラスです。
- *
- */
-NyARSingleDetectMarker = ASKlass('NyARSingleDetectMarker', NyARCustomSingleDetectMarker,
-{
-  PF_ARTOOLKIT_COMPATIBLE : 1,
-  PF_NYARTOOLKIT : 2,
-  PF_NYARTOOLKIT_ARTOOLKIT_FITTING : 100,
-  PF_TEST2 : 201,
-  /**
-  * 検出するARCodeとカメラパラメータから、1個のARCodeを検出するNyARSingleDetectMarkerインスタンスを作ります。
-  *
-  * @param i_param
-  * カメラパラメータを指定します。
-  * @param i_code
-  * 検出するARCodeを指定します。
-  * @param i_marker_width
-  * ARコードの物理サイズを、ミリメートルで指定します。
-  * @param i_input_raster_type
-  * 入力ラスタのピクセルタイプを指定します。この値は、INyARBufferReaderインタフェイスのgetBufferTypeの戻り値を指定します。
-  * @throws NyARException
-  */
-  NyARSingleDetectMarker : function(i_param,i_code,i_marker_width,i_input_raster_type,i_profile_id)
-  {
-    if (i_profile_id == null) i_profile_id = this.PF_NYARTOOLKIT;
-    NyARCustomSingleDetectMarker.initialize.call(this);
-    this.initInstance2(i_param,i_code,i_marker_width,i_input_raster_type,i_profile_id);
-    return;
-  }
-  /**
-  * コンストラクタから呼び出す関数です。
-  * @param i_ref_param
-  * @param i_ref_code
-  * @param i_marker_width
-  * @param i_input_raster_type
-  * @param i_profile_id
-  * @throws NyARException
-  */
-  ,initInstance2 : function(
-    i_ref_param,
-    i_ref_code,
-    i_marker_width,
-    i_input_raster_type,
-    i_profile_id)
-  {
-    var th=new NyARRasterFilter_ARToolkitThreshold(100,i_input_raster_type);
-    var patt_inst;
-    var sqdetect_inst;
-    var transmat_inst;
-    switch(i_profile_id){
-    case this.PF_NYARTOOLKIT://default
-      patt_inst=new NyARColorPatt_Perspective_O2(i_ref_code.getWidth(), i_ref_code.getHeight(),4,25);
-      sqdetect_inst=new NyARSquareContourDetector_Rle(i_ref_param.getScreenSize());
-      transmat_inst=new NyARTransMat(i_ref_param);
-      break;
-    default:
-      throw new NyARException();
-    }
-    NyARCustomSingleDetectMarker.initInstance.call(this,patt_inst,sqdetect_inst,transmat_inst,th,i_ref_param,i_ref_code,i_marker_width);
-  }
-  /**
-  * i_imageにマーカー検出処理を実行し、結果を記録します。
-  *
-  * @param i_raster
-  * マーカーを検出するイメージを指定します。イメージサイズは、コンストラクタで指定i_paramの
-  * スクリーンサイズと一致し、かつi_input_raster_typeに指定した形式でなければいけません。
-  * @return マーカーが検出できたかを真偽値で返します。
-  * @throws NyARException
-  */
-  ,detectMarkerLite : function(i_raster,i_threshold)
-  {
-    (NyARRasterFilter_ARToolkitThreshold(this._tobin_filter)).setThreshold(i_threshold);
-    return NyARCustomSingleDetectMarker.detectMarkerLiteB.call(this,i_raster);
-  }
-})
-
-// END FILE: 
-
-// BEGIN FILE: 
-/*
- * PROJECT: FLARToolKit
- * --------------------------------------------------------------------------------
- * This work is based on the NyARToolKit developed by
- *   R.Iizuka (nyatla)
- * http://nyatla.jp/nyatoolkit/
- *
- * The FLARToolKit is ActionScript 3.0 version ARToolkit class library.
- * Copyright (C)2008 Saqoosha
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this framework; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * For further information please contact.
- *  http://www.libspark.org/wiki/saqoosha/FLARToolKit
- *  <saq(at)saqoosha.net>
- *
- *  http://nyatla.jp/nyatoolkit/
- *  <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
- *
- * For further information of this class, please contact.
- * http://sixwish.jp
- * <rokubou(at)gmail.com>
- */
-
-/**
- * ...
- * @author tarotarorg
- */
-FLARIdMarkerData = ASKlass('FLARIdMarkerData',
-{
-  /**
-   * パケットデータをVectorで表現。（最大パケット数がモデル7での21+(1)なので、22で初期化している）
-   */
-  _packet : new IntVector(22)
-  ,_model : 0
-  ,_controlDomain : 0
-  ,_controlMask : 0
-  ,_check : 0
-  ,_dataDot : 0
-  ,packetLength : 0
-  ,FLARIdMarkerData : function()
-  {
-  }
-  ,isEqual : function(i_target)
-  {
-    if (i_target == null || !(i_target instanceof FLARIdMarkerData)) {
-      return false;
-    }
-    var s = i_target;
-    if (s.packetLength != this.packetLength    ||
-      s._check != this._check          ||
-      s._controlDomain != this._controlDomain  ||
-      s._controlMask != this._controlMask    ||
-      s._dataDot != this._dataDot        ||
-      s._model != this._model){
-      return false;
-    }
-    for(var i = s.packetLength - 1; i>=0; i--){
-      if(s._packet[i] != this._packet[i]){
-        return false;
-      }
-    }
-    return true;
-  }
-  ,copyFrom : function(i_source)
-  {
-    var s = i_source;
-    if (s == null) return;
-    this._check = s._check;
-    this._controlDomain = s._controlDomain;
-    this._controlMask = s._controlMask;
-    this._dataDot = s._dataDot;
-    this._model = s._model;
-    this.packetLength = s.packetLength;
-    for (var i = s.packetLength - 1; i >= 0; i--) {
-      this._packet[i] = s._packet[i];
-    }
-    return;
-  }
-///////////////////////////////////////////////////////////////////////////////////
-// setters
-///////////////////////////////////////////////////////////////////////////////////
-  ,setModel : function(value)
-  {
-    this._model = value;
-  }
-  ,setControlDomain : function(value)
-  {
-    this._controlDomain = value;
-  }
-  ,setControlMask : function(value)
-  {
-    this._controlMask = value;
-  }
-  ,setCheck : function(value)
-  {
-    this._check = value;
-  }
-  ,setPacketData : function(index, data)
-  {
-    if (index < this.packetLength) {
-      this._packet[index] = data;
-    } else {
-      throw ("packet index over " + index + " >= " + this.packetLength);
-    }
-  }
-  ,setDataDotLength : function(value)
-  {
-    this._dataDot = value;
-  }
-  ,setPacketLength : function(value)
-  {
-    this.packetLength = value;
-  }
-///////////////////////////////////////////////////////////////////////////////////
-// getters
-///////////////////////////////////////////////////////////////////////////////////
-  ,dataDotLength : function() { return this._dataDot; }
-  ,model : function() { return this._model; }
-  ,controlDomain : function() { return this._controlDomain; }
-  ,controlMask : function() { return this._controlMask; }
-  ,check : function() { return this._check; }
-  ,getPacketData : function(index)
-  {
-    if (this.packetLength <= index) throw new ArgumentError("packet index over");
-    return this._packet[index];
-  }
-})
-
-
-FLARDetectIdMarkerResult = ASKlass('FLARDetectIdMarkerResult',
-{
-  arcode_id : 0
-  ,direction : 0
-  ,markerdata : new FLARIdMarkerData()
-  ,square : new NyARSquare()
-})
-FLARDetectIdMarkerResultStack = ASKlass('FLARDetectIdMarkerResultStack', NyARObjectStack,
-{
-  FLARDetectIdMarkerResultStack : function(i_length)
-  {
-    NyARObjectStack.initialize.call(this,i_length);
-  }
-  ,createArray : function(i_length)
-  {
-    var ret= new Array(i_length);
-    for (var i =0; i < i_length; i++){
-      ret[i] = new FLARDetectIdMarkerResult();
-    }
-    return (ret);
-  }
-})
-
-/**
- * detectMarkerのコールバック関数
- */
-FLARMultiIdMarkerDetectCB = ASKlass('FLARMultiIdMarkerDetectCB',
-{
-  //公開プロパティ
-  result_stack : new FLARDetectIdMarkerResultStack(NyARDetectMarker.AR_SQUARE_MAX)
-  ,square : new FLARSquare()
-  ,marker_data : null
-  ,threshold : 0
-  ,direction : 0
-  ,_ref_raster : null
-  ,_current_data : null
-  ,_data_temp : null
-  ,_prev_data : null
-  ,_id_pickup : new NyIdMarkerPickup()
-  ,_coordline : null
-  ,_encoder : null
-  ,__tmp_vertex : NyARIntPoint2d.createArray(4)
-  ,_marker_param : new NyIdMarkerParam()
-  ,_maker_pattern : new NyIdMarkerPattern()
-  ,FLARMultiIdMarkerDetectCB : function(i_param,i_encoder)
-  {
-    this._coordline=new NyARCoord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor());
-    this._data_temp=i_encoder.createDataInstance();
-    this._current_data=i_encoder.createDataInstance();
-    this._encoder=i_encoder;
-    return;
-  }
-  /**
-   * Initialize call back handler.
-   */
-  ,init : function(i_raster)
-  {
-    this.marker_data=null;
-    this.result_stack.clear();
-    this._id_pickup.init();
-    this._ref_raster=i_raster;
-  }
-  ,_previous_verts : {}
-  /**
-   * 矩形が見付かるたびに呼び出されます。
-   * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。
-   */
-  ,onSquareDetect : function(i_sender,i_coordx,i_coordy,i_coor_num,i_vertex_index)
-  {
-    //輪郭座標から頂点リストに変換
-    var vertex=this.__tmp_vertex;
-    vertex[0].x=i_coordx[i_vertex_index[0]];
-    vertex[0].y=i_coordy[i_vertex_index[0]];
-    vertex[1].x=i_coordx[i_vertex_index[1]];
-    vertex[1].y=i_coordy[i_vertex_index[1]];
-    vertex[2].x=i_coordx[i_vertex_index[2]];
-    vertex[2].y=i_coordy[i_vertex_index[2]];
-    vertex[3].x=i_coordx[i_vertex_index[3]];
-    vertex[3].y=i_coordy[i_vertex_index[3]];
-    var param=this._marker_param;
-    var patt_data=this._maker_pattern;
-    // 評価基準になるパターンをイメージから切り出す
-    var cv;
-    if (window.DEBUG) {
-      cv = document.getElementById('debugCanvas').getContext('2d');
-      cv.fillStyle = 'blue';
-      for (var i=0; i<4; i++) {
-        cv.fillRect(vertex[i].x-2, vertex[i].y-2, 5, 5);
-      }
-    }
-    var cx=0,cy=0;
-    for (var i=0; i<4; i++) {
-      cx += vertex[i].x;
-      cy += vertex[i].y;
-    }
-    cx /= 4;
-    cy /= 4;
-    var pick = this._id_pickup.pickFromRaster(this._ref_raster,vertex, patt_data, param);
-    if (!pick) {
-      if (window.DEBUG) {
-        cv.fillStyle = '#ff0000';
-        cv.fillText('No pick', cx+3, cy);
-      }
-      return;
-    }
-    //エンコード
-    var enc = this._encoder.encode(patt_data,this._data_temp);
-    if(!enc){
-      return;
-    }
-    this._current_data.copyFrom(this._data_temp);
-    this.marker_data = this._current_data;//みつかった。
-    this.threshold = param.threshold;
-    this.direction = param.direction;
-    //マーカ情報を記録する。
-    var result = this.result_stack.prePush();
-    result.direction = this.direction;
-    result.markerdata.copyFrom(this.marker_data);
-    result.arcode_id = this.getId(result.markerdata);
-    if (window.DEBUG) {
-      cv.fillStyle = '#00ffff';
-      cv.fillText(result.arcode_id, cx+3, cy);
-    }
-    //新しく認識、または継続認識中に更新があったときだけ、Square情報を更新する。
-    //ココから先はこの条件でしか実行されない。
-    var sq = result.square;
-    //directionを考慮して、squareを更新する。
-    var i;
-    for(i=0;i<4;i++){
-      var idx=(i+4 - param.direction) % 4;
-      this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coordx,i_coordy,i_coor_num,sq.line[i]);
-    }
-    for (i= 0; i < 4; i++) {
-      //直線同士の交点計算
-      if(!NyARLinear.crossPos(sq.line[i],sq.line[(i + 3) % 4],sq.sqvertex[i])){
-        throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK
-      }
-    }
-  }
-  ,getId : function(data)
-  {
-    var currId;
-    if (data.packetLength > 4) {
-      currId = -1;
-    }else{
-      currId=0;
-      //最大4バイト繋げて１個のint値に変換
-      for (var i = 0; i < data.packetLength; i++ ) {
-        currId = (currId << 8) | data.getPacketData(i);
-      }
-    }
-    return currId;
-  }
-})
-
-FLARMultiIdMarkerDetector = ASKlass('FLARMultiIdMarkerDetector',
-{
-  _is_continue : false
-  ,_square_detect : null
-  ,_offset : null
-  ,_current_threshold : 110
-  // [AR]検出結果の保存用
-  ,_bin_raster : null
-  ,_tobin_filter : null
-  ,_callback : null
-  ,_data_current : null
-  ,_threshold_detect : null
-  ,_transmat : null
-  ,FLARMultiIdMarkerDetector : function(i_param ,i_marker_width)
-  {
-    var scr_size = i_param.getScreenSize();
-    var encoder = new FLARIdMarkerDataEncoder_RawBit();
-    // 解析オブジェクトを作る
-    this._square_detect = new FLARSquareContourDetector(scr_size);
-    this._callback = new FLARMultiIdMarkerDetectCB(i_param, encoder);
-    this._transmat = new NyARTransMat(i_param);
-    // ２値画像バッファを作る
-    this._bin_raster = new FLARBinRaster(scr_size.w, scr_size.h);
-    //ワーク用のデータオブジェクトを２個作る
-    this._data_current = encoder.createDataInstance();
-    this._tobin_filter = new FLARRasterFilter_Threshold(110);
-    this._threshold_detect = new FLARRasterThresholdAnalyzer_SlidePTile(15, 4);
-    this._offset = new NyARRectOffset();
-    this._offset.setSquare(i_marker_width);
-    return;
-  }
-  ,detectMarkerLite : function(i_raster, i_threshold)
-  {
-    // サイズチェック
-    if (!this._bin_raster.getSize().isEqualSize_int(i_raster.getSize().w, i_raster.getSize().h)) {
-      throw new FLARException();
-    }
-    // ラスタを２値イメージに変換する.
-    this._tobin_filter.setThreshold(i_threshold);
-    this._tobin_filter.doFilter(i_raster, this._bin_raster);
-    // スクエアコードを探す(第二引数に指定したマーカ、もしくは新しいマーカを探す。)
-    this._callback.init(this._bin_raster);
-    this._square_detect.detectMarkerCB(this._bin_raster, this._callback);
-    //見付かった数を返す。
-    return this._callback.result_stack.getLength();
-  }
-  /**
-   * i_indexのマーカーに対する変換行列を計算し、結果値をo_resultへ格納します。 直前に実行したdetectMarkerLiteが成功していないと使えません。
-   *
-   * @param i_index
-   * マーカーのインデックス番号を指定します。 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。
-   * @param o_result
-   * 結果値を受け取るオブジェクトを指定してください。
-   * @throws NyARException
-   */
-  ,getTransformMatrix : function(i_index, o_result)
-  {
-    var result = this._callback.result_stack.getItem(i_index);
-    // 一番一致したマーカーの位置とかその辺を計算
-    if (this._is_continue) {
-      this._transmat.transMatContinue(result.square, this._offset, o_result);
-    } else {
-      this._transmat.transMat(result.square, this._offset, o_result);
-    }
-    return;
-  }
-  ,getIdMarkerData : function(i_index)
-  {
-    var result = new FLARIdMarkerData();
-    result.copyFrom(this._callback.result_stack.getItem(i_index).markerdata);
-    return result;
-  }
-  /**
-   * i_indexのマーカーのARCodeインデックスを返します。
-   *
-   * @param i_index
-   * マーカーのインデックス番号を指定します。 直前に実行したdetectMarkerLiteの戻り値未満かつ0以上である必要があります。
-   * @return
-   */
-  ,getARCodeIndex : function(i_index)
-  {
-    return this._callback.result_stack.getItem(i_index).arcode_id;
-  }
-  /**
-   * 検出したマーカーの方位を返します。
-   * 0,1,2,3の何れかを返します。
-   *
-   * @return Returns whether any of 0,1,2,3.
-   */
-  ,getDirection : function(i_index)
-  {
-    return this._callback.result_stack.getItem(i_index).direction;
-  }
-  /**
-   * 検出した FLARSquare 1 個返す。検出できなかったら null。
-   * @return Total return detected FLARSquare 1. Detection Dekinakattara null.
-   */
-  ,getSquare : function(i_index)
-  {
-    return this._callback.result_stack.getItem(i_index).square;
-  }
-  /**
-   * getTransmationMatrixの計算モードを設定します。
-   *
-   * @param i_is_continue
-   * TRUEなら、transMatContinueを使用します。 FALSEなら、transMatを使用します。
-   */
-  ,setContinueMode : function(i_is_continue)
-  {
-    this._is_continue = i_is_continue;
-  }
-  /**
-   * 2値化した画像を返却します。
-   *
-   * @return 画像情報を返却します
-   */
-  ,thresholdedBitmapData : function()
-  {
-    try {
-      return ((this._bin_raster).getBuffer());
-    } catch (e) {
-      return null;
-    }
-    return null;
-  }
-})
-/**
- * detectMarkerのコールバック関数
- */
-FLARSingleIdMarkerDetectCB = ASKlass('FLARSingleIdMarkerDetectCB',
-{
-  //公開プロパティ
-  square : new FLARSquare()
-  ,marker_data : null
-  ,threshold : 0
-  ,direction : 0
-  ,_ref_raster : null
-  ,_current_data : null
-  ,_data_temp : null
-  ,_prev_data : null
-  ,_id_pickup : new NyIdMarkerPickup()
-  ,_coordline : null
-  ,_encoder : null
-  ,__tmp_vertex : NyARIntPoint2d.createArray(4)
-  ,_marker_param : new NyIdMarkerParam()
-  ,_maker_pattern : new NyIdMarkerPattern()
-  ,FLARSingleIdMarkerDetectCB : function(i_param,i_encoder)
-  {
-    this._coordline=new NyARCoord2Linear(i_param.getScreenSize(),i_param.getDistortionFactor());
-    this._data_temp=i_encoder.createDataInstance();
-    this._current_data=i_encoder.createDataInstance();
-    this._encoder=i_encoder;
-    return;
-  }
-  /**
-   * Initialize call back handler.
-   */
-  ,init : function(i_raster,i_prev_data)
-  {
-    this.marker_data=null;
-    this._prev_data=i_prev_data;
-    this._ref_raster=i_raster;
-  }
-  /**
-   * 矩形が見付かるたびに呼び出されます。
-   * 発見した矩形のパターンを検査して、方位を考慮した頂点データを確保します。
-   */
-  ,onSquareDetect : function(i_sender,i_coordx,i_coordy,i_coor_num,i_vertex_index)
-  {
-    //既に発見済なら終了
-    if(this.marker_data!=null){
-      return;
-    }
-    //輪郭座標から頂点リストに変換
-    var vertex=this.__tmp_vertex;
-    vertex[0].x=i_coordx[i_vertex_index[0]];
-    vertex[0].y=i_coordy[i_vertex_index[0]];
-    vertex[1].x=i_coordx[i_vertex_index[1]];
-    vertex[1].y=i_coordy[i_vertex_index[1]];
-    vertex[2].x=i_coordx[i_vertex_index[2]];
-    vertex[2].y=i_coordy[i_vertex_index[2]];
-    vertex[3].x=i_coordx[i_vertex_index[3]];
-    vertex[3].y=i_coordy[i_vertex_index[3]];
-    var param=this._marker_param;
-    var patt_data=this._maker_pattern;
-    // 評価基準になるパターンをイメージから切り出す
-    var pick = this._id_pickup.pickFromRaster(this._ref_raster,vertex, patt_data, param)
-    if (window.DEBUG) {
-      var cv = document.getElementById('debugCanvas').getContext('2d');
-      cv.fillStyle = 'blue';
-      for (var i=0; i<4; i++) {
-        cv.fillRect(vertex[i].x-2, vertex[i].y-2, 5, 5);
-      }
-    }
-    if (!pick){
-      return;
-    }
-    this.direction = param.direction;
-    //エンコード
-    if(!this._encoder.encode(patt_data,this._data_temp)){
-      return;
-    }
-    //継続認識要求されている？
-    if (this._prev_data==null){
-      //継続認識要求なし
-      this._current_data.copyFrom(this._data_temp);
-    }else{
-      //継続認識要求あり
-      if(!this._prev_data.isEqual((this._data_temp))){
-        return;//認識請求のあったIDと違う。
-      }
-    }
-    //新しく認識、または継続認識中に更新があったときだけ、Square情報を更新する。
-    //ココから先はこの条件でしか実行されない。
-    var sq=this.square;
-    //directionを考慮して、squareを更新する。
-    var i;
-    for(i=0;i<4;i++){
-      var idx=(i+4 - param.direction) % 4;
-      this._coordline.coord2Line(i_vertex_index[idx],i_vertex_index[(idx+1)%4],i_coordx,i_coordy,i_coor_num,sq.line[i]);
-    }
-    for (i= 0; i < 4; i++) {
-      //直線同士の交点計算
-      if(!NyARLinear.crossPos(sq.line[i],sq.line[(i + 3) % 4],sq.sqvertex[i])){
-        throw new NyARException();//ここのエラー復帰するならダブルバッファにすればOK
-      }
-    }
-    this.threshold=param.threshold;
-    this.marker_data=this._current_data;//みつかった。
-  }
-})
-FLARSingleIdMarkerDetector = ASKlass('FLARSingleIdMarkerDetector', {
-  _is_continue : false
-  ,_square_detect : null
-  ,_offset : null
-  ,_is_active : null
-  ,_current_threshold : 110
-  // [AR]検出結果の保存用
-  ,_bin_raster : null
-  ,_tobin_filter : null
-  ,_callback : null
-  ,_data_current : null
-  ,_threshold_detect : null
-  ,_transmat : null
-  ,FLARSingleIdMarkerDetector : function(i_param ,i_marker_width)
-  {
-    var scr_size = i_param.getScreenSize();
-    var encoder = new FLARIdMarkerDataEncoder_RawBit();
-    // 解析オブジェクトを作る
-    this._square_detect = new FLARSquareContourDetector(scr_size);
-    this._callback = new FLARSingleIdMarkerDetectCB(i_param, encoder);
-    this._transmat = new NyARTransMat(i_param);
-    // ２値画像バッファを作る
-    this._bin_raster = new FLARBinRaster(scr_size.w, scr_size.h);
-    //ワーク用のデータオブジェクトを２個作る
-    this._data_current = encoder.createDataInstance();
-    this._tobin_filter = new FLARRasterFilter_Threshold(110);
-    this._threshold_detect = new FLARRasterThresholdAnalyzer_SlidePTile(15, 4);
-    this._offset = new NyARRectOffset();
-    this._offset.setSquare(i_marker_width);
-    return;
-  }
-  ,detectMarkerLite : function(i_raster, i_threshold)
-  {
-    // サイズチェック
-    if (!this._bin_raster.getSize().isEqualSize_int(i_raster.getSize().w, i_raster.getSize().h)) {
-      throw new FLARException();
-    }
-    // ラスタを２値イメージに変換する.
-    this._tobin_filter.setThreshold(i_threshold);
-    this._tobin_filter.doFilter(i_raster, this._bin_raster);
-    // スクエアコードを探す(第二引数に指定したマーカ、もしくは新しいマーカを探す。)
-    this._callback.init(this._bin_raster, this._is_active?this._data_current:null);
-    this._square_detect.detectMarkerCB(this._bin_raster, this._callback);
-    // 見つからない場合はfalse
-    if(this._callback.marker_data==null){
-      this._is_active=false;
-      return false;
-    }
-    this._is_active = true;
-    this._data_current.copyFrom(this._callback.marker_data);
-    return true;
-  }
-  ,getIdMarkerData : function()
-  {
-    var result = new FLARIdMarkerData();
-    result.copyFrom(this._callback.marker_data);
-    return result;
-  }
-  ,getDirection : function()
-  {
-    return this._callback.direction;
-  }
-  ,getTransformMatrix : function(o_result)
-  {
-    if (this._is_continue) this._transmat.transMatContinue(this._callback.square, this._offset, o_result);
-    else this._transmat.transMat(this._callback.square, this._offset, o_result);
-    return;
-  }
-  ,setContinueMode : function(i_is_continue)
-  {
-    this._is_continue = i_is_continue;
-  }
-})
-
-FLARIdMarkerDataEncoder_RawBit = ASKlass('FLARIdMarkerDataEncoder_RawBit',
-{
-  _DOMAIN_ID : 0
-  /**
-   * 制御ドット作成時のmodに使う値
-   */
-  ,_mod_data : new IntVector([7, 31, 127, 511, 2047, 4095])
-  ,encode : function(i_data,o_dest)
-  {
-    var dest = o_dest;
-    if (dest == null) {
-      throw new FLARException("type of o_dest must be \"FLARIdMarkerData\"");
-    }
-    if(i_data.ctrl_domain != this._DOMAIN_ID) {
-      return false;
-    }
-    dest.setCheck(i_data.check);
-    dest.setControlDomain(i_data.ctrl_domain);
-    dest.setControlMask(i_data.ctrl_mask);
-    dest.setModel(i_data.model);
-    //データドット数計算
-    var resolution_len = toInt(i_data.model * 2 - 1); //trace("resolution", resolution_len);
-    dest.setDataDotLength(resolution_len);
-    //データドット数が、「(2 * model値 - 1)^2」となり、この2乗の元となる値がresolution_lenで、
-    //パケット数は「(int)(データドット数 / 8) + 1」（最後に足す1はパケット0）となる
-    var packet_length = toInt((resolution_len * resolution_len) / 8) + 1;
-    // trace("packet", packet_length);
-    dest.setPacketLength(packet_length);
-    var sum = 0;
-    for(var i=0;i<packet_length;i++){
-      dest.setPacketData(i, i_data.data[i]);
-      // trace("i_data[",i,"]",i_data.data[i]);
-      sum += i_data.data[i];
-    }
-    //チェックドット値計算
-    sum = sum % this._mod_data[i_data.model - 2];
-    // trace("check dot", i_data.check, sum);
-    //チェックドット比較
-    if(i_data.check!=sum){
-      return false;
-    }
-    return true;
-  }
-  ,createDataInstance : function()
-  {
-    return new FLARIdMarkerData();
-  }
-})
-// END FILE: 
-
-// BEGIN FILE: NyUtils.js 
-/*
- * JSARToolkit
- * --------------------------------------------------------------------------------
- * This work is based on the original ARToolKit developed by
- *   Hirokazu Kato
- *   Mark Billinghurst
- *   HITLab, University of Washington, Seattle
- * http://www.hitl.washington.edu/artoolkit/
- *
- * And the NyARToolkitAS3 ARToolKit class library.
- *   Copyright (C)2010 Ryo Iizuka
- *
- * JSARToolkit is a JavaScript port of NyARToolkitAS3.
- *   Copyright (C)2010 Ilmari Heikkinen
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- * For further information please contact.
- *  ilmari.heikkinen@gmail.com
- *
- */
-
-
-
-
-
-/**
- * マーカの周辺領域からビットマップを取得する方法を提供します。
- * 比較的負荷が大きいので、連続してパターンを取得し続ける用途には向いていません。
- *
- */
-TransformedBitmapPickup = ASKlass('TransformedBitmapPickup', NyARColorPatt_Perspective_O2,
-{
-  _work_points : NyARIntPoint2d.createArray(4),
-  _ref_perspective : null,
-  /**
-   *
-   * @param i_width
-   * 取得するビットマップの幅
-   * @param i_height
-   * 取得するビットマップの解像度
-   * @param i_resolution
-   * resolution of reading pixel per point. ---- 取得時の解像度。高解像度のときは1を指定してください。低解像度のときは2以上を指定します。
-   */
-  TransformedBitmapPickup : function(i_ref_cparam,i_width,i_height,i_resolution)
-  {
-    NyARColorPatt_Perspective_O2.initialize.call(this,i_width, i_height, i_resolution, 0);
-    this._ref_perspective = i_ref_cparam;
-  }
-  /**
-   * This ,retrieves bitmap from the area defined by RECT : function(i_l,i_t,i_r,i_b) above transform matrix i_base_mat.
-   * ----
-   * この関数は、basementで示される平面のAで定義される領域から、ビットマップを読み出します。
-   * 例えば、8cmマーカでRECT(i_l,i_t,i_r,i_b)に-40,0,0,-40.0を指定すると、マーカの左下部分の画像を抽出します。
-   *
-   * マーカから離れた場所になるほど、また、マーカの鉛直方向から外れるほど誤差が大きくなります。
-   * @param i_src_imege
-   * 詠み出し元の画像を指定します。
-   * @param i_l
-   * 基準点からの左上の相対座標（x）を指定します。
-   * @param i_t
-   * 基準点からの左上の相対座標（y）を指定します。
-   * @param i_r
-   * 基準点からの右下の相対座標（x）を指定します。
-   * @param i_b
-   * 基準点からの右下の相対座標（y）を指定します。
-   * @param i_base_mat
-   * @return 画像の取得の成否を返す。
-   */
-  ,pickupImage2d : function(i_src_imege,i_l,i_t,i_r,i_b,i_base_mat)
-  {
-    var cp00, cp01, cp02, cp11, cp12;
-    cp00 = this._ref_perspective.m00;
-    cp01 = this._ref_perspective.m01;
-    cp02 = this._ref_perspective.m02;
-    cp11 = this._ref_perspective.m11;
-    cp12 = this._ref_perspective.m12;
-    //マーカと同一平面上にある矩形の4個の頂点を座標変換して、射影変換して画面上の
-    //頂点を計算する。
-    //[hX,hY,h]=[P][RT][x,y,z]
-    //出力先
-    var poinsts = this._work_points;
-    var yt0,yt1,yt2;
-    var x3, y3, z3;
-    var m00=i_base_mat.m00;
-    var m10=i_base_mat.m10;
-    var m20=i_base_mat.m20;
-    //yとtの要素を先に計算
-    yt0=i_base_mat.m01 * i_t+i_base_mat.m03;
-    yt1=i_base_mat.m11 * i_t+i_base_mat.m13;
-    yt2=i_base_mat.m21 * i_t+i_base_mat.m23;
-    // l,t
-    x3 = m00 * i_l + yt0;
-    y3 = m10 * i_l + yt1;
-    z3 = m20 * i_l + yt2;
-    poinsts[0].x = toInt ((x3 * cp00 + y3 * cp01 + z3 * cp02) / z3);
-    poinsts[0].y = toInt ((y3 * cp11 + z3 * cp12) / z3);
-    // r,t
-    x3 = m00 * i_r + yt0;
-    y3 = m10 * i_r + yt1;
-    z3 = m20 * i_r + yt2;
-    poinsts[1].x = toInt ((x3 * cp00 + y3 * cp01 + z3 * cp02) / z3);
-    poinsts[1].y = toInt ((y3 * cp11 + z3 * cp12) / z3);
-    //yとtの要素を先に計算
-    yt0=i_base_mat.m01 * i_b+i_base_mat.m03;
-    yt1=i_base_mat.m11 * i_b+i_base_mat.m13;
-    yt2=i_base_mat.m21 * i_b+i_base_mat.m23;
-    // r,b
-    x3 = m00 * i_r + yt0;
-    y3 = m10 * i_r + yt1;
-    z3 = m20 * i_r + yt2;
-    poinsts[2].x = toInt ((x3 * cp00 + y3 * cp01 + z3 * cp02) / z3);
-    poinsts[2].y = toInt ((y3 * cp11 + z3 * cp12) / z3);
-    // l,b
-    x3 = m00 * i_l + yt0;
-    y3 = m10 * i_l + yt1;
-    z3 = m20 * i_l + yt2;
-    poinsts[3].x = toInt ((x3 * cp00 + y3 * cp01 + z3 * cp02) / z3);
-    poinsts[3].y = toInt ((y3 * cp11 + z3 * cp12) / z3);
-    return this.pickFromRaster(i_src_imege, poinsts);
-  }
-})
-// END FILE: NyUtils.js
-
diff --git a/examples/marker_ar/awe.marker_ar.js b/examples/marker_ar/awe.marker_ar.js
deleted file mode 100755
index 566d359..0000000
--- a/examples/marker_ar/awe.marker_ar.js
+++ /dev/null
@@ -1,524 +0,0 @@
-
-
-;(function(awe) {
-
-  var jsartoolkit_camera_matrix = new Float32Array(16),
-    marker_transform_matrix = new THREE.Matrix4().elements,
-    threshold = 98,
-    marker_size = 80,
-    canvas,
-    canvas_context,
-    jsartoolkit,
-    debug_canvas,
-    frame_image,
-    detector,
-    
-    renderer,
-    awe_canvas,
-    awe_canvas_width,
-    awe_canvas_height,
-    video_stream,
-    video_element,
-    last_time = 0,
-    debug_threshold = 3,
-    
-    ar_marker_id_prefix = 'jsartoolkit_marker_',
-    ar_marker_ids = [],
-    visible_marker_ids = [],
-    jsartoolkit_marker_transform_matrix,
-    
-    tracking_ready = false,
-    tracking_scene_ready = false,
-    tracking_config_ready = false,
-    video_stream_ready = false,
-    vars_ready = false,
-    
-    tracking_enabled = false,
-    
-    tracking_pov, 
-    tracking_scene, 
-    tracking_lights = {},
-    
-    old_render, 
-    old_lights_add,
-    old_lights_update,
-    old_lights_delete,
-    
-    existing_pois = {},
-    offset_scale = 1,
-    x_offset = 0,
-    y_offset = 0;
-
-  for (var i=0;i<100;i++) {
-    ar_marker_ids.push(ar_marker_id_prefix+i);
-  }
-  
-
-  function convert_matrix_from_to(src, dst){
-    dst[0] = src.m00;
-    dst[1] = -src.m10;
-    dst[2] = src.m20;
-    dst[3] = 0;
-    dst[4] = src.m01;
-    dst[5] = -src.m11;
-    dst[6] = src.m21;
-    dst[7] = 0;
-    dst[8] = -src.m02;
-    dst[9] = src.m12;
-    dst[10] = -src.m22;
-    dst[11] = 0;
-    dst[12] = src.m03;
-    dst[13] = -src.m13;
-    dst[14] = src.m23;
-    dst[15] = 1;
-  }
-  
-  function setup_vars(){
-    renderer = awe.renderer(),
-    awe_canvas = renderer.get_canvas();
-
-    awe_canvas_width = awe_canvas.clientWidth;
-    awe_canvas_height = awe_canvas.clientHeight;
-    
-    
-    if (document.getElementById('jsartoolkit_canvas')) {
-      canvas = document.getElementById('jsartoolkit_canvas');
-    }
-    else {
-      canvas = document.createElement('canvas');
-      canvas.id = "jsartoolkit_canvas";
-      canvas.style.display = "none";
-      
-      document.body.appendChild(canvas);
-      canvas_context = canvas.getContext('2d');
-    }
-    if (window.DEBUG) {
-      if (document.getElementById('debugCanvas')) {
-        debug_canvas = document.getElementById('debugCanvas');
-      }
-      else {
-        debug_canvas = document.createElement('canvas');
-        debug_canvas.id = "debugCanvas";
-        document.body.appendChild(debug_canvas);
-      }
-    }
-    
-    vars_ready = true;
-  }
-  function setup_tracking() {
-    if (tracking_ready) {
-      return;
-    }
-    setup_tracking_scene();
-    resize_tracking();
-    setup_tracking_config();
-    tracking_ready = true;
-  }
-  function resize_tracking(){
-    if (!vars_ready) {
-      console.warn('vars not ready');
-      return;
-    };
-    
-    awe_canvas_width = awe_canvas.clientWidth;
-    awe_canvas_height = awe_canvas.clientHeight;
-    var aspect = awe_canvas_width / awe_canvas_height;
-    
-    canvas.width = awe_canvas_width;
-    canvas.height = awe_canvas_height;
-    if (debug_canvas) {
-      debug_canvas.width = awe_canvas_width;
-      debug_canvas.height = awe_canvas_height;
-    }
-    
-    tracking_pov.set_aspect(aspect);
-    tracking_pov.update_projection_matrix();
-    
-    offset_scale = 1;
-    y_offset = 0;
-    x_offset = 0;
-    
-    if (video_stream_ready) {
-      var video_aspect = video_element.videoWidth / video_element.videoHeight;
-      
-      if (video_aspect > aspect) { // slimmer viewport than video -> trim video sides
-        x_offset = (((video_element.videoWidth * awe_canvas_height) / video_element.videoHeight ) - awe_canvas_width) / 2;
-        offset_scale = video_element.videoHeight / awe_canvas_height;
-      }
-      else if (video_aspect < aspect) {
-        y_offset = (((video_element.videoHeight * awe_canvas_width) / video_element.videoWidth ) - awe_canvas_height) / 2;
-        offset_scale = video_element.videoWidth / awe_canvas_width;
-      }
-      
-    }
-    
-    
-    if (tracking_config_ready) {
-      jsartoolkit.changeScreenSize(awe_canvas_width, awe_canvas_height);
-      jsartoolkit.copyCameraMatrix(jsartoolkit_camera_matrix, tracking_pov.near, tracking_pov.far);
-      tracking_pov.set_projection_matrix(jsartoolkit_camera_matrix);
-    }
-  }
-  
-  function destroy_tracking_config(){
-    delete(jsartoolkit);
-    delete(jsartoolkit_camera_matrix);
-    delete(detector);
-    delete(frame_image);
-    delete(jsartoolkit_marker_transform_matrix);
-    
-    tracking_config_ready = false;
-  }
-  
-  function setup_tracking_config(){
-    if (tracking_config_ready) { destroy_tracking_config();  }
-    if (!tracking_pov) {
-      console.warn('setting up config too early');
-      return;
-    }
-    
-    jsartoolkit = new FLARParam(awe_canvas_width, awe_canvas_height, tracking_pov.fov);
-    jsartoolkit_marker_transform_matrix = new NyARTransMatResult();
-
-    detector = new FLARMultiIdMarkerDetector(jsartoolkit,marker_size);
-    detector.setContinueMode(true);
-    frame_image = new NyARRgbRaster_Canvas2D(canvas);
-    
-    jsartoolkit.copyCameraMatrix(jsartoolkit_camera_matrix, 10, tracking_pov.far);
-    
-    tracking_pov.set_projection_matrix(jsartoolkit_camera_matrix);
-    tracking_config_ready = true;
-  }
-  
-  function add_light(awe_light){
-    if (tracking_lights[awe_light.id]) { console.warn('trying to add light that already exists', arguments); return; }
-    var mesh = awe_light.get_mesh();
-    var light = mesh.clone();
-    tracking_scene._add_child(light);
-    tracking_lights[awe_light.id] = light;
-  }
-  function delete_light(awe_light_id){
-    if (!tracking_lights[awe_light_id]) { console.warn('trying to delete light rhat doesnt exist', arguments); return; }
-    tracking_scene._remove_child(tracking_lights[awe_light_id]);
-    delete tracking_lights[awe_light_id];
-  }
-  function update_light(awe_light){
-    if (!tracking_lights[awe_light.id]) { console.warn('trying to update light rhat doesnt exist', arguments); return; }
-    var mesh = awe_light.get_mesh();
-    var light = tracking_lights[awe_light.id];
-    ['visibility','castShadow','receiveShadow'].forEach(function(param){
-      if (mesh[param] != undefined) {
-        light[param] = mesh[param];
-      }
-    });
-    // position
-    light.position.set(mesh.position.x, mesh.position.y, mesh.position.z);
-    
-    // rotation
-    light.quaternion.copy(mesh.quaternion);
-    
-    // scale
-    light.scale.set(mesh.scale.x, mesh.scale.y, mesh.scale.z);
-    
-  }
-  
-  function setup_tracking_scene(){
-    if (tracking_scene_ready) { return; }
-
-    if (awe.renderer()) {
-      if (!tracking_pov) {
-        awe.povs.add({
-          id: 'tracking_pov'
-        });
-        tracking_pov = awe.povs.view('tracking_pov');
-        
-        awe.scenes.add({
-          id: 'tracking_scene'
-        });
-        tracking_scene = awe.scenes.view('tracking_scene');
-        
-        
-        old_render = awe.render;
-        awe.render = function() {
-          var three_renderer = awe.renderer().get_three_renderer();
-          three_renderer.autoClear = false;
-          
-          three_renderer.clear();
-          three_renderer.render(tracking_scene.get_mesh(), tracking_pov.get_mesh());
-          three_renderer.render(awe.scene().get_mesh(), awe.pov().get_mesh());
-          awe.scene_needs_rendering = 0;
-        }
-        old_lights_add = awe.lights.add;
-        old_lights_update = awe.lights.update;
-        old_lights_delete = awe.lights.delete;
-        
-        // TODO duplicate lights
-        awe.lights.list().forEach(add_light);
-        
-        awe.lights.add = function(){
-          var result = old_lights_add.apply(this, arguments);
-          var ids;
-          if (!Array.isArray(result.id)) {
-            ids = [result.id];
-          }
-          else {
-            ids = result.id;
-          }
-          awe.lights.list({exact: {id: ids}}).forEach(add_light);
-          return result;
-        }
-        awe.lights.update = function(){
-          var result = old_lights_update.apply(this, arguments);
-          var ids = Object.keys(result);
-          awe.lights.list({exact: {id: ids}}).forEach(update_light);
-          return result;
-        }
-        awe.lights.delete = function(){
-          var result = old_lights_delete.apply(this, arguments);
-          var ids;
-          if (!Array.isArray(result.id)) {
-            ids = [result.id];
-          }
-          else {
-            ids = result.id;
-          }
-          ids.forEach(delete_light);
-          return result;
-        }
-        
-        tracking_scene_ready = true;
-      }
-      get_poi_ids();
-    }
-  }
-  
-  function add_stream_event(){
-    awe.events.add([{
-      id: 'jsartoolkit_gum_ready',
-      
-      register: function(handler) {
-        window.addEventListener('gum_ready', handler, false);
-      },
-      unregister: function(handler){
-        window.removeEventListener('gum_ready', handler, false);
-      },
-      handler: function(e) {
-        video_stream = awe.video_stream();
-        video_element = video_stream.get_video_element();
-        
-        video_stream_ready = true;
-        
-        if (tracking_ready) {
-          resize_tracking();
-        } 
-      }
-    }]);
-  }
-  
-  function add_ar_events(){
-
-    awe.events.add([
-    {
-      id: 'jsartoolkit_tracking',
-      
-      register: function(handler) {
-        window.addEventListener('tick', handler, false);
-      },
-      unregister: function(handler){
-        window.removeEventListener('tick', handler, false);
-      },
-      handler: function(event) {
-        if (!tracking_enabled) {
-          return;
-        }
-        if (!vars_ready) {
-          setup_vars();
-        }
-        if (!tracking_ready) {
-          setup_tracking();
-        }
-        if (!video_stream_ready) {
-          return;
-        }
-        if (video_element.ended) { video_element.play(); }
-        if (video_element.paused) { return; }
-        if (video_element.currentTime == last_time) { return; }
-//         if (video_element.currentTime - last_time < debug_threshold) { return; }
-
-        last_time = video_element.currentTime;
-        
-        try {
-          canvas_context.drawImage(video_element, x_offset*offset_scale, y_offset*offset_scale, video_element.videoWidth-2*offset_scale*x_offset, video_element.videoHeight-2*offset_scale*y_offset, 0, 0, canvas.width, canvas.height);
-        }
-        catch(e) { /* TODO */ }
-        canvas.changed = true;
-        var detected_count;
-        try {
-          detected_count = detector.detectMarkerLite(frame_image, threshold);
-        }
-        catch(e){ console.log(e); }
-        
-        var event_data = {};
-        var markers_to_hide = visible_marker_ids.slice();
-        var markers_previously_visible = visible_marker_ids.slice();
-        visible_marker_ids = [];
-
-        for (var i=0; i<detected_count; i++) {
-          var id = detector.getIdMarkerData(i);
-          var detected_marker_id = -1;
-          if (id.packetLength <= 4) {
-            detected_marker_id = 0;
-            for (var j = 0; j < id.packetLength; j++) {
-              detected_marker_id = (detected_marker_id << 8) | id.getPacketData(j);
-            }
-          }
-          detector.getTransformMatrix(i, jsartoolkit_marker_transform_matrix);
-          convert_matrix_from_to(jsartoolkit_marker_transform_matrix, marker_transform_matrix);
-          event_data[detected_marker_id] = {
-            transform: Object.asCopy(marker_transform_matrix)
-          };
-          if (existing_pois[detected_marker_id]) {
-            visible_marker_ids.push(detected_marker_id);
-            if (markers_to_hide.indexOf(detected_marker_id) > -1) {
-              markers_to_hide.splice(markers_to_hide.indexOf(detected_marker_id), 1);
-            }
-            try {
-              var poi = awe.pois.view(existing_pois[detected_marker_id]),
-                mesh = poi.get_mesh();
-             
-              mesh.matrixAutoUpdate = false;
-              mesh.matrix.setFromArray(Object.asCopy(marker_transform_matrix));
-              mesh.matrixWorldNeedsUpdate = true;
-              
-              poi.update({
-                visible: true
-              });
-            }
-            catch(e){
-              console.error(e);
-            }
-          }
-        }
-
-        // hide all others        
-        var poi_to_hide = markers_to_hide.map(function(marker_id) {
-          return existing_pois[marker_id];
-        });
-        if (poi_to_hide.length) {
-          awe.pois.update({
-            data: {
-              visible: false
-            },
-            where: { id: poi_to_hide }
-          });
-        }
-        
-        // trigger custom event for other user-defined interactions
-        var event = new CustomEvent('ar_tracking_marker', { detail: event_data });
-        window.dispatchEvent(event);  
-      }
-    },
-    {
-      id: 'jsartoolkit_pov_projection_matrix',
-      register: function(handler) {
-        window.addEventListener('renderer_resized', handler, false);
-      },
-      unregister: function(handler){
-        window.removeEventListener('renderer_resized', handler, false);
-      },
-      handler: function(e) {
-        if (tracking_enabled) {
-          resize_tracking();
-          setup_tracking_config();
-        }
-      }
-    }
-    ]);
-  }
-  
-  function remove_ar_events(){
-    awe.events.delete('jsartoolkit_gum_ready');
-    awe.events.delete('jsartoolkit_tracking');
-    awe.events.delete('jsartoolkit_pov_projection_matrix');
-  }
-
-  function get_poi_ids(){
-    existing_pois = {};
-    var pois = awe.pois.list({id: ar_marker_id_prefix});
-    pois.forEach(function(poi){
-
-      existing_pois[poi.id.replace(ar_marker_id_prefix, '')] = poi.id;
-      poi.update({visible: false});
-      var parent = poi.parent();
-      if (tracking_scene) {
-//       if (!(parent instanceof awe.povs._item_constructor)) {
-        tracking_scene._add_child(poi);
-//       }
-      }
-    });
-    
-  }
-  var awe_pov = awe.povs._item_constructor;
-    
-  awe.plugins.add([{
-    id: 'jsartoolkit',
-    auto_register: true,
-    capabilities: ['gum','webgl'],
-    enable: function(){
-      // check if any image pois got added in meantime
-      resize_tracking();
-      setup_tracking_config();
-      get_poi_ids();
-      tracking_enabled = true;
-    },
-    disable: function(){
-      destroy_tracking_config();
-      tracking_enabled = false;
-    },
-    register: function(plugin_data){
-      
-      THREE.Matrix4.prototype.setFromArray = function(m){
-        this.set(
-          m[0], m[4], m[8], m[12],
-          m[1], m[5], m[9], m[13],
-          m[2], m[6], m[10], m[14],
-          m[3], m[7], m[11], m[15]
-        );
-        
-        var clone = this.clone();
-        var v1 = new THREE.Vector3();
-        var v2 = new THREE.Vector3();
-        var q = new THREE.Quaternion();
-        clone.decompose(v1, q, v2);
-        
-        var m1 = new THREE.Matrix4();
-        m1.makeScale(-1,-1,-1);
-        var m2 = new THREE.Matrix4();
-        m2.makeRotationY(Math.PI);
-        this.multiply(m1);
-        this.multiply(m2);
-      };
-      
-      add_ar_events();
-      if (!awe.video_stream()) {
-        add_stream_event();
-        awe.setup_stream();
-      }
-      else if (awe.video_stream().is_stream_ready()) {
-        video_stream = awe.video_stream();
-        video_element = video_stream.get_video_element();
-        video_stream_ready = true;
-      }
-      else {
-        add_stream_event();
-      }
-
-    },
-    unregister: function(plugin_data){
-      awe.render = old_render;
-      remove_ar_events();
-    }
-  }]);
-  
-})(window.awe);
-
diff --git a/examples/marker_ar/awe_orange_square.png b/examples/marker_ar/awe_orange_square.png
deleted file mode 100644
index cf242db7fd7d1004e2f13987aa6096e7b0cb2b71..0000000000000000000000000000000000000000
GIT binary patch
diff --git a/examples/marker_ar/index.html b/examples/marker_ar/index.html
deleted file mode 100755
index 3024617..0000000
--- a/examples/marker_ar/index.html
+++ /dev/null
@@ -1,129 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>AWE Marker AR demo</title>
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0" />
-<meta charset="utf-8"/>
-<style type="text/css">
-* {
-	margin: 0;
-	padding: 0;
-}
-#container {
-	position: absolute;
-	left: 0;
-	top: 0;
-	bottom: 0;
-	right: 0;
-	overflow: hidden;
-}
-#debugCanvas {
-  position: absolute;
-  z-index: 999;
-  opacity: 0.5;
-  top: 50%;
-  left: 50%;
-  transform: translate(-50%, -50%);
-}
-</style>
-</head>
-<body>
-  <canvas id="debugCanvas"></canvas>
-<div id="container"></div>
-<script type="text/javascript" src="../../js/awe-v8.js"></script>
-<script type="text/javascript" src="../../js/awe-loader.js"></script>
-<script type="text/javascript">
-//   DEBUG = true;
-  window.addEventListener('load', function() {
-    window.awe.init({
-      device_type: awe.AUTO_DETECT_DEVICE_TYPE,
-      settings: {
-      	container_id: 'container',
-        default_camera_position: { x:0, y:0, z:0 },
-        default_lights:[
-          {
-            id: 'ambient_light',
-            type: 'ambient',
-            color: 0x666666
-          },
-          {
-            id: 'hemi',
-            type: 'hemisphere',
-            color: 0xCCCCCC,
-          },
-        ],
-      },
-      ready: function() {
-        var d = '?_='+Date.now();
-        
-        awe.util.require([
-          {
-            capabilities: ['gum','webgl'],
-            files: [ 
-              // base libraries
-              [ '../../js/awe-standard-dependencies.js', '../../js/awe-standard.js'+d],
-              // plugin dependencies
-              ['awe-jsartoolkit-dependencies.js','../../js/plugins/StereoEffect.js', '../../js/plugins/VREffect.js'],
-              // plugins
-              ['awe.marker_ar.js'+d,'../../js/plugins/awe.rendering_effects.js'+d]
-            ],
-            success: function() { 
-							awe.setup_scene();
-			        
-							awe.settings.update({data:{value: 'ar'}, where:{id: 'view_mode'}})
-							
-              /*
-                Binding a POI to a jsartoolkit marker is easy
-                - First add the awe-jsartoolkit-dependencies.js plugin (see above)
-                - Then select a marker image you'd like to use
-                - Then add the matching number as a suffix for your POI id (e.g. _64)
-                NOTE: See 64.png in this directory or https://github.com/kig/JSARToolKit/blob/master/demos/markers
-                This automatically binds your POI to that marker id - easy!
-              */
-			        awe.pois.add({ id:'jsartoolkit_marker_64', position: { x:0, y:0, z:0 }, visible: false });
-			        awe.projections.add({ 
-			          id:'marker_projection', 
-								geometry: { shape: 'cube', x:50, y:50, z:50 },
-                position: { x:0, y:0, z:0 },
-                rotation: { x:0, y:0, z:180 },
-			          material:{ type: 'phong', color: 0xFFFFFF }, 
-                texture: { path: 'awe_orange_square.png' },
-                visible: false,
-			        }, { poi_id: 'jsartoolkit_marker_64' });
-			        
-			        awe.pois.add({ id:'fixed_poi', position: { x:100, y:0, z:-250 }, visible: true });
-			        awe.projections.add({ 
-			          id:'fixed_projection', 
-								geometry: { shape: 'cube', x:50, y:50, z:50 },
-                position: { x:0, y:0, z:0 },
-                rotation: { x:0, y:0, z:0 },
-			          material:{ type: 'phong', color: 0xFFFFFF }, 
-                texture: { path: 'awe_orange_square.png' },
-			        }, { poi_id: 'fixed_poi' });
-			        
-			        // animate the fixed POI
-              awe.projections.update({
-                data:{
-                  animation: { duration: 5, persist: 0, repeat: Infinity },
-                  rotation: { y: 360 },
-                },
-                where:{ id:"fixed_projection" },
-              });
-
-			        awe.plugins.view('render_effects').enable();
-			        awe.plugins.view('jsartoolkit').enable();
-			      },
-          },
-          {
-            capabilities: [],
-            success: function() { 
-		          document.body.innerHTML = '<p>Try this demo in the latest version of Chrome or Firefox on a PC or Android device</p>';
-            },
-          },
-        ]);
-      }
-    });
-  });
-</script>
-</body>
-</html>
diff --git a/examples/stereo_ar/awe.stereo_click.js b/examples/stereo_ar/awe.stereo_click.js
deleted file mode 100755
index 84eee32..0000000
--- a/examples/stereo_ar/awe.stereo_click.js
+++ /dev/null
@@ -1,99 +0,0 @@
-(function(awe) {
-
-  var projector,
-    ray,
-    camera,
-    canvas;
-  
-  var _ready = false;
-  var _enabled = false;
-  
-	awe.plugins.add([{
-		id: 'object_clicked_stereo',
-    auto_register: true,
-    enable: function(){
-      _enabled = true;
-    },
-    disable: function(){
-      _enabled = false;
-    },
-		register: function(){
-			awe.events.add({
-				id: 'click_stereo',
-				capabilities: ['webgl'],
-				register: function(handler) {
-					window.addEventListener('click', handler, false);
-				},
-				unregister: function(handler){
-					window.removeEventListener('click', handler, false);
-				},
-				handler: function(e) {
-					if (!_enabled) {
-  					console.log('click plugin disabled');
-  					return;
-					}
-					if (!_ready) {
-            projector = new THREE.Projector();
-            ray = new THREE.Raycaster();
-            camera = awe.pov().get_mesh();
-            canvas = awe.renderer().get_canvas();
-            _ready = true;
-					}
-          var settings = awe.util.get_settings('click_handling');
-          if (settings.click_handling === undefined || settings.click_handling == true) {
-            var stereo_plugin = awe.plugins.view('render_effects');
-            var view_count = awe.settings.view('view_count') ? awe.settings.view('view_count').value() : 'mono';
-            
-            var client_x = e.clientX;
-            var viewport_width = canvas.clientWidth;
-            
-            if (view_count == 'stereo' && stereo_plugin && stereo_plugin.enabled) {
-              var cameras = stereo_plugin.get_stereo_cameras();
-              viewport_width = canvas.clientWidth/2;
-              if (client_x > canvas.clientWidth/2) {
-                // right viewport half
-                camera = cameras.right;
-                client_x -= canvas.clientWidth/2;
-              }
-              else {
-                // left viewport half
-                camera = cameras.left;
-              }
-              client_x *= 2;
-            }
-            
-            var x = (client_x/canvas.clientWidth) * 2 - 1;
-            var y = -(e.clientY/canvas.clientHeight) * 2 + 1;
-            var mouse_vector = new THREE.Vector3(x, y, 1);
-            mouse_vector.unproject(camera); 
-            var direction = mouse_vector.sub(camera.position).normalize();
-            ray.set(camera.position, direction);
-            var intersects = ray.intersectObjects(awe.projections.list({ type:'clickable' }), true);
-            if (intersects.length) {
-              var mesh = _get_clicked_projection(intersects[0].object);
-              if (mesh && mesh.projection_id) {
-                intersects[0].projection_id = mesh.projection_id;
-                var event = new CustomEvent('object_clicked', { detail:intersects[0] });
-                window.dispatchEvent(event);
-              }
-            }
-          }
-				}
-			});
-		},
-		unregister: function(){
-			awe.events.delete('click');
-		}
-	}]);
-  function _get_clicked_projection(mesh) {
-    if (mesh.projection_id == undefined) {
-      if (mesh.parent == undefined) {
-        return undefined;
-      } else {
-        return _get_clicked_projection(mesh.parent);
-      }
-    } else {
-      return mesh;
-    }
-  }
-})(window.awe);
diff --git a/examples/stereo_ar/awe_by_buildAR.png b/examples/stereo_ar/awe_by_buildAR.png
deleted file mode 100755
index d95c760ddc061e2f58c7bc3be2d03fe6d3f92de4..0000000000000000000000000000000000000000
GIT binary patch
diff --git a/examples/stereo_ar/index.html b/examples/stereo_ar/index.html
deleted file mode 100755
index ef320e0..0000000
--- a/examples/stereo_ar/index.html
+++ /dev/null
@@ -1,229 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>AWE Stereo click AR demo</title>
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0" />
-<meta charset="utf-8"/>
-<style type="text/css">
-* {
-	margin: 0;
-	padding: 0;
-}
-#container {
-	position: absolute;
-	left: 0;
-	top: 0;
-	bottom: 0;
-	right: 0;
-	overflow: hidden;
-}
-#info {
-  position: absolute;
-  z-index: 999;
-  top: 10px;
-  left: 10px;
-  background: #fff;
-  color: #000;
-  padding: 3px;
-}
-
-</style>
-</head>
-<body>
-<div id="info"></div>
-<div id="container"></div>
-<script type="text/javascript" src="../../js/awe-v8.js"></script>
-<script type="text/javascript" src="../../js/awe-loader.js"></script>
-<script type="text/javascript">
-//   DEBUG = true;
-  function add_pois() {
-  
-    // add some points of interest (poi) for each of the compass points
-    awe.pois.add({ id:'north', position: { x:0, y:0, z:200 } });
-    awe.pois.add({ id:'north_east', position: { x:200, y:0, z:200 } });
-    awe.pois.add({ id:'east', position: { x:200, y:0, z:0 } });
-    awe.pois.add({ id:'south_east', position: { x:200, y:0, z:-200 } });
-    awe.pois.add({ id:'south', position: { x:0, y:0, z:-200 } });
-    awe.pois.add({ id:'south_west', position: { x:-200, y:0, z:-200 } });
-    awe.pois.add({ id:'west', position: { x:-200, y:0, z:0 } });
-    awe.pois.add({ id:'north_west', position: { x:-200, y:0, z:200 } });
-  
-    // add projections to each of the pois
-    awe.projections.add({ 
-      id:'n', 
-      geometry:{ shape:'cube', x:50, y:50, z:50 }, 
-      rotation:{ x:30, y:30, z:0 },
-      material:{ 
-        type: 'phong',
-        color:0xFF0000, 
-      },
-    }, { poi_id: 'north' });
-  
-    awe.projections.add({ 
-      id:'ne', 
-      geometry:{ shape:'sphere', radius:40 }, 
-      material:{ 
-        type: 'phong',
-        color:0xCC000f, 
-      },
-    }, { poi_id: 'north_east' });
-  
-    awe.projections.add({ 
-      id:'e', 
-      geometry:{ shape:'cube', x:50, y:50, z:50 }, 
-      rotation:{ x:30, y:30, z:0 },
-      material:{ 
-        type: 'phong',
-        color:0x00FF00, 
-      },
-    }, { poi_id: 'east' });
-  
-    awe.projections.add({ 
-      id:'se', 
-      geometry:{ shape:'sphere', radius:40 }, 
-      material:{ 
-        type: 'phong',
-        color:0x34CCfa, 
-      },
-    }, { poi_id: 'south_east' });
-  
-    awe.projections.add({ 
-      id:'s', 
-      geometry:{ shape:'cube', x:50, y:50, z:50 }, 
-      rotation:{ x:30, y:30, z:0 },
-      material:{ 
-        type: 'phong',
-        color:0xF0FF0F, 
-      },
-    }, { poi_id: 'south' });
-  
-    awe.projections.add({ 
-      id:'sw', 
-      geometry:{ shape:'sphere', radius:40 }, 
-      material:{ 
-        type: 'phong',
-        color:0x00CCCC, 
-      },
-    }, { poi_id: 'south_west' });
-  
-    awe.projections.add({ 
-      id:'w', 
-      geometry:{ shape:'cube', x:50, y:50, z:50 }, 
-      rotation:{ x:30, y:30, z:0 },
-      material:{ 
-        type: 'phong',
-        color:0x0000FF, 
-      },
-    }, { poi_id: 'west' });
-  
-    awe.projections.add({ 
-      id:'nw', 
-      geometry:{ shape:'sphere', radius:40 }, 
-      material:{ 
-        type: 'phong',
-        color:0xCCffCC, 
-      },
-    }, { poi_id: 'north_west' });
-  }
-  window.addEventListener('load', function() {
-    window.awe.init({
-      device_type: awe.AUTO_DETECT_DEVICE_TYPE,
-      settings: {
-      	container_id: 'container',
-        default_camera_position: { x:0, y:0, z:0 },
-        default_lights:[
-          {
-            id: 'hemi',
-            type: 'hemisphere',
-            color: 0xAAAAAA,
-          },
-        ],
-      },
-      ready: function() {
-
-        awe.util.require([
-          {
-            capabilities: ['gum','webgl'],
-            files: [ 
-              [ '../../js/awe-standard-dependencies.js', '../../js/awe-standard.js'],
-              ['../../js/plugins/StereoEffect.js', '../../js/plugins/VREffect.js'],
-              [
-                '../../js/plugins/awe.rendering_effects.js', 
-                '../../js/plugins/awe-standard-object_clicked_or_focused.js', 
-                '../basic/awe.gyro.js',
-              ]
-            ],
-            success: function() { 
-							awe.setup_scene();
-			        
-						
-              add_pois();
-              
-              // object clicked is not set to auto-register
-  						var plugin = awe.plugins.view('object_clicked');
-  						if (plugin) {
-    						plugin.register();
-    						plugin.enable();
-  						}
-			        
-              awe.plugins.view('render_effects').enable();
-			        
-			        if (awe.plugins.view('geo_ar')) {
-  			        awe.plugins.view('geo_ar').enable();
-  			      }
-			
-			        var info = document.getElementById('info');
-			        // 'ar' will not do anything if gum is unavailable
-							awe.settings.update({data:{value: 'ar'}, where:{id: 'view_mode'}})
-							// stereo setting will only work if a vr/stereo plugin is available and supported by the device
-							awe.settings.update({data:{value: 'stereo'}, where:{id: 'view_count'}})
-              
-              var object_clicked = false;     
-			        awe.events.add([
-  			        {
-    			        id: '_click',
-    			        register: function(handler){
-      			        window.addEventListener('object_clicked', handler, false);
-    			        },
-    			        unregister: function(handler){
-      			        window.removeEventListener('object_clicked', handler, false);
-      			      },
-      			      handler: function(e) {
-        			      console.log(e);
-        			      object_clicked = true;
-        			      info.innerHTML = 'Clicked projection ID: '+e.detail.projection_id;
-      			      }
-  			        },
-  			        {
-    			        id: '_no_click',
-    			        register: function(handler){
-      			        window.addEventListener('click', handler, false);
-    			        },
-    			        unregister: function(handler){
-      			        window.removeEventListener('click', handler, false);
-      			      },
-      			      handler: function(e) {
-        			      if (object_clicked) {
-          			      object_clicked = false;
-        			      }
-        			      else {
-          			      info.innerHTML = 'scene clicked';
-        			      }
-      			      }
-  			        }
-			        ])
-			      },
-          },
-          {
-            capabilities: [],
-            success: function() { 
-		          document.body.innerHTML = '<p>Try this demo in the latest version of Chrome or Firefox on a PC or Android device</p>';
-            },
-          },
-        ]);
-      }
-    });
-  });
-</script>
-</body>
-</html>
diff --git a/js/awe-loader-min.js b/js/awe-loader-min.js
deleted file mode 120000
index d7bdf9f..0000000
--- a/js/awe-loader-min.js
+++ /dev/null
@@ -1 +0,0 @@
-awe-loader.js
\ No newline at end of file
diff --git a/js/awe-loader.js b/js/awe-loader.js
deleted file mode 100755
index 197cfbd..0000000
--- a/js/awe-loader.js
+++ /dev/null
@@ -1,1217 +0,0 @@
-
-
-// BEGIN FILE:  awe-loader.js file
-/*
-
-  The MIT License
-
-  Copyright (c) 2013 Rob Manson & Malgorzata Wierzbicka, http://buildAR.com. 
-  All rights reserved.
-
-  Permission is hereby granted, free of charge, to any person obtaining a copy
-  of this software and associated documentation files (the "Software"), to deal
-  in the Software without restriction, including without limitation the rights
-  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-  copies of the Software, and to permit persons to whom the Software is
-  furnished to do so, subject to the following conditions:
-
-  The above copyright notice and this permission notice shall be included in
-  all copies or substantial portions of the Software.
-
-  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-  THE SOFTWARE.
-
-*/
-
-
-(function(window) {
-  var ID_FIELD = "id";
-  var this_awe;
-  var _audio_context;
-  
-  
-  function awe_v8_item(data, v8_datastore){
-    
-    var datastore;
-    var data;
-
-    this.setup = function(initial_data){
-      // do we validate fields in any way?
-      data = initial_data; //_clone(initial_data);
-      this[ID_FIELD] = initial_data[ID_FIELD]
-    };
-    this._get_datastore = function(){
-      return datastore;
-    };
-    this._get_data = function(){
-      return data
-    };
-    this._get_data_value = function(key){
-      return data[key];
-    };
-    this._set_data_value = function(key, value){
-      data[key] = value;
-      this._values_updated();
-      return true;
-    };
-    // TBD if we want this
-    this.get_data = function(){
-      return data
-    };
-    
-    try {
-      if (!data) {
-        throw 'Please provide item data';
-      }
-      if (!v8_datastore) {
-        throw 'Please provide a v8_datastore this item belongs to';
-      }
-      if (v8_datastore+'' != 'awe_v8_object') {
-        throw 'Please provide a valid v8_datastore this item belongs to';
-      }
-      datastore = v8_datastore;
-      this.setup(data)
-    }
-    catch(e) {
-      console.error(e);
-    }
-    
-    return this;
-  }
-  
-  awe_v8_item.prototype.constructor = awe_v8_item;
-  awe_v8_item.prototype.toString = function(){
-    var id = this._get_data_value(ID_FIELD)
-    return this.constructor.name+' - '+ID_FIELD+': '+id;
-  }
-  awe_v8_item.prototype.update = function(data){
-    var datastore = this._get_datastore();
-    datastore.update({
-      data: data,
-      where: { id: this[ID_FIELD] }
-    });
-  };
-  awe_v8_item.prototype._values_updated = function(){};
-  
-  // TBD if we keep this
-  awe_v8_item.prototype.private_properties = [ID_FIELD];
-  
-  /// awe base object class
-  function awe_object(data, datastore){
-    awe_v8_item.call(this, data, datastore);
-  }
-  awe_object.prototype = Object.create(awe_v8_item.prototype);
-  awe_object.prototype.constructor = awe_object;
-  awe_object.prototype.toString = function(){
-    var id = this._get_data_value(ID_FIELD)
-    return this.constructor.name+' '+id+': '+this._get_data_value('value');
-  };
-  // value getter & setter
-  awe_object.prototype.value = function(val){
-    if (arguments.length) {
-      this._set_data_value('value', val);
-    }
-    return this._get_data_value('value');
-  };
-  
-  
-  // awe_capability class
-  function awe_capability(data, datastore){
-    awe_object.call(this, data, datastore);
-  }
-  awe_capability.prototype = Object.create(awe_object.prototype);
-  awe_capability.prototype.constructor = awe_capability;
-
-  // awe_setting class
-  function awe_setting(data, datastore){
-    awe_object.call(this, data, datastore);
-  }
-  awe_setting.prototype = Object.create(awe_object.prototype);
-  awe_setting.prototype.constructor = awe_setting;
-  
-
-  // awe_event class
-  function awe_event(data, datastore){
-    data._register = data.register;
-    data._unregister = data.unregister;
-    this.registered = false;
-    awe_object.call(this, data, datastore);
-    this.register();
-  }
-  awe_event.prototype = Object.create(awe_object.prototype);
-  awe_event.prototype.constructor = awe_event;
-  awe_event.prototype.register = function(){
-    if (this.registered) {
-      return;
-    }
-    var device_types = this._get_data_value('device_types');
-    
-    if (!device_types || Object.keys(device_types).length == 0 || device_types[this_awe.device_type()]) {
-      
-      var f = this._get_data_value('_register');
-      var handler = this._get_data_value('handler');
-      if (f && typeof(f) == 'function') {
-        f.call(this, handler);
-        this.registered = true;
-      }
-    }
-  };
-  awe_event.prototype.unregister = function(){
-    if (!this.registered) {
-      return;
-    }
-    var f = this._get_data_value('_unregister');
-    var handler = this._get_data_value('handler');
-    if (f && typeof(f) == 'function') {
-      f.call(this, handler);
-      this.registered = false;
-    }
-  };
-
-  
-  
-  
-  // awe_plugin class
-  function awe_plugin(data, datastore){
-    data._register = data.register;
-    data._unregister = data.unregister;
-    data._enable = data.enable;
-    data._disable = data.disable;
-    awe_object.call(this, data, datastore);
-    this.registered = false;
-    this.enabled = false;
-
-    if (data.api) {
-      // expose the api 
-      var self = this;
-      Object.keys(data.api).forEach(function(key, val){
-        if (typeof data.api[key] == 'function' && !self[key]) {
-          self[key] = data.api[key];
-        }
-      });
-    }
-    if (data.auto_register === undefined || data.auto_register == true) {
-      this.register(data.data);
-    }
-  }
-  awe_plugin.prototype = Object.create(awe_object.prototype);
-  awe_plugin.prototype.constructor = awe_plugin;
-  awe_plugin.prototype.register = function(){
-    if (this.registered) {
-      return;
-    }
-    var f = this._get_data_value('_register');
-    if (f && typeof(f) == 'function') {
-      f.call(this);
-      this.registered = true;
-    }
-  };
-  awe_plugin.prototype.unregister = function(){
-    if (!this.registered) {
-      return;
-    }
-    var f = this._get_data_value('_unregister');
-    if (f && typeof(f) == 'function') {
-      f.call(this);
-      this.registered = false;
-    }
-  };
-  awe_plugin.prototype.enable = function(){
-    if (this.enabled) {
-      return;
-    }
-    var f = this._get_data_value('_enable');
-    if (f && typeof(f) == 'function') {
-      f.call(this);
-      this.enabled = true;
-    }
-  };
-  awe_plugin.prototype.disable = function(){
-    if (!this.enabled) {
-      return;
-    }
-    var f = this._get_data_value('_disable');
-    if (f && typeof(f) == 'function') {
-      f.call(this);
-      this.enabled = false;
-    }
-  };
-  
-  
-  
-  function _verify_view_config(config) {
-    return {
-      pois: config && Array.isArray(config.pois) ? config.pois : [],
-      projections: config && Array.isArray(config.projections) ? config.projections : [],
-      povs: config && Object.prototype.toString.call(config.povs) ? config.povs : {},
-      lights: config && Array.isArray(config.lights) ? config.lights : []
-    };
-  }
-  // awe_view class
-  function awe_view(data, datastore){
-    var self = this;
-    var data_load_handler = data.load_handler;
-    var data_unload_handler = data.unload_handler;
-    
-    delete(data.unload_handler);
-    delete(data.load_handler);
-    
-    var load_handler = function(){
-      self.pre_load_handler.apply(self, arguments);
-      if (data_load_handler && typeof(data_load_handler) == 'function') {
-        data_load_handler.apply(self, arguments);
-      }
-      self.post_load_handler.apply(self, arguments);
-    }
-    var unload_handler = function(){
-      self.pre_unload_handler.apply(self, arguments);
-      if (data_unload_handler && typeof(data_unload_handler) == 'function') {
-        data_unload_handler.apply(self, arguments);
-      }
-      self.post_unload_handler.apply(self, arguments);
-    }
-    data.load_handler = load_handler;
-    data.unload_handler = unload_handler;
-    
-    awe_object.call(this, data, datastore);
-    this.config = _verify_view_config(data.config);
-  }
-  awe_view.prototype = Object.create(awe_object.prototype);
-  awe_view.prototype.constructor = awe_view;
-  // default config structure
-  awe_view.prototype.handler_data = {};
-  awe_view.prototype.config = {
-    
-    pois: [/* $id1, $id2, ... */],           // just ids or full object config ??? 
-    projections: [],    // I'm more towards the IDs-only option 
-    lights: [],         // we can store the scene objects config elsewhere
-    povs: []            // and then either just show poi on view load or add if not in scene yet, but object config exists 
-    
-  }
-  
-  awe_view.prototype.pre_load_handler = function(){
-    console.log('pre_load_handler', this.name)
-  };
-  awe_view.prototype.post_load_handler = function(){
-    console.log('post_load_handler', this.name)
-  };
-  awe_view.prototype.pre_unload_handler = function(){
-    console.log('pre_unload_handler', this.name)
-  };
-  awe_view.prototype.post_unload_handler = function(){
-    console.log('post_unload_handler', this.name)
-  };
-  
-  awe_view.prototype.get_config = function(){
-    return this._get_data_value('config');
-  };
-  awe_view.prototype.get_title = function(){
-    return this._get_data_value('title');
-  };
-  awe_view.prototype.get_handler_data = function(){
-    return this._get_data_value('handler_data');
-  };
-  awe_view.prototype.load = function(){
-    var load_handler = this._get_data_value('load_handler');
-    var config = this.get_config();
-    var self = this;
-    var object_types = ['poi','light','pov','projection'];
-    object_types.forEach(function(type){
-      var all_objects = this_awe[type+'s'].list();
-      var view_objects = Array.isArray(config[type+'s']) ? config[type+'s'] : [];
-      all_objects.forEach(function(object){
-        if (object.update) { 
-          object.update({
-            visible: view_objects.indexOf(object.id) != -1
-          });
-        }
-        else {
-          console.log('not yet an awe object', object)
-        }
-      });
-    });
-    
-    if (load_handler && typeof(load_handler)) {
-      // load_handler needs to be promise-like function
-      return new Promise(function(resolve, reject){
-        load_handler.call(self, resolve, reject);
-      });
-    }
-    // resolve immediately
-    return Promise.resolve();
-  };
-  awe_view.prototype.unload = function(){
-    var self = this;
-    var unload_handler = this._get_data_value('unload_handler');
-    
-    if (unload_handler && typeof(unload_handler) == 'function') {
-      // unload_handler needs to be promise-like function
-      return new Promise(function(resolve, reject){
-        unload_handler.call(self, resolve, reject);
-      });
-    }
-    // resolve immediately
-    return Promise.resolve();
-  };
-
-
-
-  if (!window.awe) {
-    function awe() {
-      var initialized = false;
-      var version = {
-	      awe: '1.0a'
-	     };
-
-      this.constructor.prototype.capabilities = new awe_v8();
-      this.constructor.prototype.capabilities._item_constructor = awe_capability;
-      this.constructor.prototype.capabilities.add = function(BODY, HEAD) {
-        if (!BODY) { BODY = {}; }
-        if (!HEAD) { HEAD = {}; }
-        if (!Array.isArray(BODY)) {
-          BODY = [BODY];
-        }
-        var self = this,
-          result = []
-        BODY.forEach(function(item){
-          var s = new awe_capability(item, self);
-          result.push(s);
-        })
-        return this.constructor.prototype.add.call(this, result, HEAD); // super
-      }
-      
-
-      this.constructor.prototype.views = new awe_v8();
-      this.constructor.prototype.views._item_constructor = awe_view;
-      this.constructor.prototype.views.add = function(BODY, HEAD) {
-        if (!BODY) { BODY = {}; }
-        if (!HEAD) { HEAD = {}; }
-        if (!Array.isArray(BODY)) {
-          BODY = [BODY];
-        }
-        var self = this,
-          result = []
-        BODY.forEach(function(item){
-          var s = new awe_view(item, self);
-          s._values_updated();
-          result.push(s);
-        })
-        return this.constructor.prototype.add.call(this, result, HEAD); // super
-      }
-
-      this.constructor.prototype.settings = new awe_v8();
-      this.constructor.prototype.settings._item_constructor = awe_setting;
-      this.constructor.prototype.settings.add = function(BODY, HEAD) {
-        if (!BODY) { BODY = {}; }
-        if (!HEAD) { HEAD = {}; }
-        if (!Array.isArray(BODY)) {
-          BODY = [BODY];
-        }
-        var self = this,
-          result = []
-        BODY.forEach(function(item){
-          var s = new awe_setting(item, self);
-          result.push(s);
-        })
-        return this.constructor.prototype.add.call(this, result, HEAD); // super
-      }
-      // set default settings
-      // NOTE: override this in your code to customize how you want your awe.js app to behave
-      
-      this.settings.add([
-        {
-          id: 'debug',
-          value: false,
-        },
-        {
-          id: 'geo',
-          value:{
-            get_location: false,
-          }
-        },
-        {
-          id: 'auto_start',
-          value: false,
-        },
-        {
-          id: 'renderer',
-          value: 'webgl',
-        },
-        {
-          id: 'start_video_stream',
-          value: false,
-        },
-        {
-            id: 'fps',
-            value: 60,
-        },
-        {
-          id: 'default_lights',
-          value: [
-            {
-              id: 'hemisphere_light',
-              type: 'hemisphere',
-              color: 0xffffff,
-            },
-          ],
-        },
-      ]);
-
-      this.constructor.prototype.events = new awe_v8();
-      this.constructor.prototype.events._item_constructor = awe_event;
-      this.constructor.prototype.events.add = function(BODY, HEAD) {
-        if (!BODY) { BODY = {}; }
-        if (!HEAD) { HEAD = {}; }
-        if (!Array.isArray(BODY)) {
-          BODY = [BODY];
-        }
-        var self = this,
-          result_body = [];
-        BODY.forEach(function(item){
-          if (!this_awe.events.view(item.id)) {
-            // prevent duplicate runs of register() that cannot be later unregister()ed via events.delete()
-            var s = new awe_event(item, self);
-            result_body.push(s);
-          }
-        });
-        
-        return this.constructor.prototype.add.call(this, result_body, HEAD); // super;
-      }
-      this.constructor.prototype.events.delete = function(BODY, HEAD) {
-        if (!BODY) { BODY = {}; }
-        if (!HEAD) { HEAD = {}; }
-        var event;
-        if (typeof BODY == 'string' || typeof BODY == 'number') {
-          BODY = { id: BODY };
-        }
-        if (BODY.id) {
-          event = this_awe.events.view(BODY.id);
-        }
-        if (event) {
-          var handler = event._get_data_value('handler');
-          event.unregister(handler);
-        }
-        return this.constructor.prototype.delete.call(this, BODY, HEAD); // super
-      }
-
-      this.constructor.prototype.plugins = new awe_v8();
-      this.constructor.prototype.plugins._item_constructor = awe_plugin;
-      this.constructor.prototype.plugins.add = function(BODY, HEAD) {
-        if (!BODY) { BODY = {}; }
-        if (!HEAD) { HEAD = {}; }
-        if (!Array.isArray(BODY)) {
-          BODY = [BODY];
-        }
-        var self = this,
-          result_body = [];
-        BODY.forEach(function(item){
-          var supported = true;
-          if (item.capabilities) {
-            var capabilities = _get_capabilities(item.capabilities.join('|'));
-            item.capabilities.forEach(function(c){
-              if (!capabilities[c]) {
-                supported = false;
-              }
-            });
-          }
-          if (supported) {
-            var s = new awe_plugin(item, self);
-            result_body.push(s);
-          }
-        })
-        return this.constructor.prototype.add.call(this, result_body, HEAD); // super
-      }
-      this.constructor.prototype.plugins.delete = function(BODY, HEAD) {
-        if (!BODY) { BODY = {}; }
-        if (!HEAD) { HEAD = {}; }
-        // tear down plugin
-        if (typeof BODY == 'string' || typeof BODY == 'number') {
-          BODY = { id: BODY };
-        }
-        if (BODY.id) {
-          plugin = this.plugins.view(BODY.id);
-        }
-        if (plugin) {
-          plugin.unregister(plugin.data);
-        }
-        return this.constructor.prototype.delete.call(this, BODY, HEAD); // super
-      }
-    
-      this.constructor.prototype.error_handler = function(e, debug) {
-        if (debug || this.debug) {
-          if (e.code && e.message) {
-            console.log('ERROR: '+e.code);
-            console.log(e.message);
-          }
-          else {
-            console.log('ERROR');
-            console.log(e);
-          }
-          if (this.debug_verbose > 0) {
-            console.log('CALLER');
-            console.log(arguments.callee.caller);
-          }
-          if (this.debug_verbose > 2) {
-            console.log(arguments.callee.caller.toString());
-          }
-        }
-      };
-      
-      this.constructor.prototype.init = function(io) {
-        if (initialized) {
-          console.log('awe was already initialized.');
-          return;
-        }
-        if (!io) { io = {}; }
-        
-        
-        if (io.settings) {
-          for (var key in io.settings) {
-            try {
-              if (this_awe.settings.view(key) !== undefined) {
-                this_awe.settings.update({
-                  data: {
-                    value: io.settings[key],
-                  },
-                  where: {
-                    id: key,
-                  }
-                });
-              }
-              else {
-                this_awe.settings.add({
-                  id: key,
-                  value: io.settings[key],
-                });
-              }
-            }
-            catch(e) { /* TODO */ }
-          }  
-        }
-        
-        if (this_awe.settings.view('debug')) {
-          this.debug = this_awe.settings.view('debug').value();
-        }
-        else {
-          this.debug = true;
-        }
-        if (this_awe.settings.view('debug_verbose')) {
-          this.debug_verbose = this_awe.settings.view('debug_verbose').value();
-        }
-        else {
-          this.debug_verbose = 1;
-        }
-        if (this_awe.settings.view('capabilities_timeout')) {
-          this.capabilities_timeout = this_awe.settings.view('capabilities_timeout').value();
-        }
-        else {
-          this.capabilities_timeout = 5000;
-        }
-
-        if (io.device_type !== undefined) {
-          if (io.device_type === true) {
-            var device_type = 'unsupported';
-            var ua = navigator.userAgent;
-            if (ua.match(/ipad/i)) {
-              device_type = 'ipad';
-            } 
-            else if (ua.match(/iphone/i)) {
-              device_type = 'iphone';
-            }
-            else if (ua.match(/android/i)) {
-              device_type = 'android';
-              // NOTE: may differentiate more here
-            }
-            else if (ua.match(/(win|os x|linux)/i)) {
-              device_type = 'pc';
-            }
-            this_awe.settings.update({ 
-              data: { 
-                value: device_type 
-              }, 
-              where: { 
-                id: 'device_type' 
-              } 
-            });
-          }
-          else {
-            this_awe.settings.update({
-              data:{
-                value: io.device_type,
-              },
-              where:{
-                id: 'device_type',
-              }
-            });
-          }
-        }
-
-        this_awe.detect_capabilities(function() {
-          var plugins = this_awe.plugins.list();
-          for (var i in plugins) {
-            plugins[i].register(plugins[i]);
-          }
-          if (io.ready) {
-            try {
-              io.ready();
-            }
-            catch(e) { /* TODO */ }
-          }
-          var event = new CustomEvent('awe_ready');
-          window.dispatchEvent(event);
-          if (this_awe.settings.view('auto_start').value()) {
-            this_awe.setup_scene();
-          }
-          initialized = true;
-        });
-      }; 
-
-      this.constructor.prototype.detect_capabilities = function(done) {
-        var io = {},
-          asynch_count = 3,
-          defaults = {
-            ajax : false,      // is ajax supported
-            geo : false,       // is geo supported
-            lat: undefined,    // only populated once location requested
-            lon: undefined,    // only populated once location requested
-            gyro : false,      // is orientation supported
-            motion : false,    // is motion supported
-            audio : false,     // is web audio supported
-            gum: false,        // is camera/microphone access supported 
-            webgl: false,      // is webgl supported
-            css3d: false,      // is css3d supported
-            storage : false,   // is local storage supported
-            sockets : false,   // are web sockets supported
-            touch : false      // touch events supported
-          };
-          
-        var finished = function() {
-          asynch_count--;
-          if (asynch_count === 0) {
-            var io_array = [];
-            for (prop in io) {
-              io_array.push({ id:prop, value:io[prop] });
-            }
-            this_awe.capabilities.add(io_array);
-            if (done && typeof(done) == 'function') {
-              done();
-            }
-          }
-        };
-        
-        for (prop in defaults) {
-          if (!io[prop]) {
-            io[prop] = defaults[prop];
-          }
-        }
-
-        // services (ajax) enabled
-        if (!!window.XMLHttpRequest || !!window.XMLHttpRequest2) {
-          io.ajax = true;
-        }
-
-        // geo enabled
-        if (!!navigator.geolocation) {
-          io.geo = true;
-          var geo = this_awe.settings.view('geo');
-          var get_location = this_awe.settings.view('geo.get_location');
-          if (geo && geo.value()) {
-            if (get_location && get_location.value()) {
-              navigator.geolocation.getCurrentPosition(function(position) {
-                this_awe.capabilities.update({ data: { value: position.coords.latitude }, where: { id: 'lat' } });
-                this_awe.capabilities.update({ data: { value: position.coords.longitude }, where: { id: 'lon' } });
-              });
-            }
-          }
-        }
-        // orientation enabled
-        if (!!window.DeviceOrientationEvent) {
-          var s1 = function(e) {
-            if (e.alpha !== null) {
-              io.gyro = true;
-            }
-            window.removeEventListener('deviceorientation', s1, true);
-            finished();
-          }
-          window.addEventListener('deviceorientation', s1, true);
-          // in case event handler never returns - eg. on a pc
-          setTimeout(function() {
-            if (!io.gyro) {
-              finished();
-            }
-          }, this_awe.capabilities_timeout);
-        }
-        else {
-          finished();
-        }
-
-        // motion enabled
-        if (!!window.DeviceMotionEvent) {
-          var s2 = function(e) {
-            if (e.acceleration !== null) {
-              io.motion = true;
-            }
-            window.removeEventListener('devicemotion', s2, true);
-            finished();
-          }
-          window.addEventListener('devicemotion', s2, true);
-          // in case event handler never returns - eg. on a pc
-          setTimeout(function() {
-            if (!io.motion) {
-              finished();
-            }
-          }, this_awe.capabilities_timeout);
-        }
-        else {
-          finished();
-        }
-
-        // getUserMedia microphone & camera access enabled
-        if (this_awe.util.get_user_media) {
-          io.gum = true;
-        }
-
-        // web audio enabled 
-        if (!!window.AudioContext) {
-          _audio_context = new AudioContext();
-        }
-        else if (!!window.webkitAudioContext) {
-          _audio_context = new webkitAudioContext();
-        }
-        if (_audio_context) {
-          io.audio = true;
-          this_awe.util.audio_context = _audio_context;
-        }
-
-        // webgl enabled
-        if (!!document.createElement('canvas').getContext('experimental-webgl') || !!document.createElement('canvas').getContext('webgl')) {
-          io.webgl = true;
-        }
-        
-        var tmp_div = document.createElement('div');
-        if (tmp_div.style.WebkitTransformStyle) {
-          tmp_div.style.WebkitTransformStyle = 'preserve-3d';
-          if (tmp_div.style.WebkitTransformStyle == 'preserve-3d') {
-            io.css3d = true;
-          }
-        }
-        else if (tmp_div.style.transformStyle) {
-          tmp_div.style.transformStyle = 'preserve-3d';
-          if (tmp_div.style.transformStyle == 'preserve-3d') {
-            io.css3d = true;
-          }
-        }
-
-        // localstorage enabled
-        if (!!window.localStorage) {
-          io.storage = true;
-        }
-
-        // websockets enabled
-        if (!!window.WebSocket || !!window.MozWebSocket || !!window.WebkitWebSocket || !!window.OWebSocket || !!window.msWebSocket || !!window.KhtmlWebSocket) {
-          io.sockets = true;
-        }
-        
-        // touch events
-        if ('ontouchstart' in window) {
-          io.touch = true;
-        }
-
-        
-        finished();
-      };
-
-      this.constructor.prototype.device_type = function() { 
-        var device_type;
-        try {
-          device_type = this.settings.view('device_type').value();
-        }
-        catch(e) { /* TODO */ };
-        return device_type;
-      };
-
-      this.constructor.prototype.ready = function() {
-        return initialized;
-      }
-      this.constructor.prototype.version = function() {
-        return version;
-      }
-
-      return this;
-    };
-    
-    function _reset_load_file_queue() {
-      return {
-        error_called: false,
-        success_called: false,
-        queue: [],
-        status: {},
-      };
-    }
-
-    var _load_file_queue = _reset_load_file_queue();
-    function _require(io) {
-      _load_file_queue = _reset_load_file_queue();
-      if (Array.isArray(io)) {
-        for (var obj in io) {
-          if (io[obj].capabilities && io[obj].files) {
-            if (!io[obj].success || typeof io[obj].success !== 'function') {
-              io[obj].success = function() { /* TODO */ }
-            }
-            if (!io[obj].error || typeof io[obj].error !== 'function') {
-              io[obj].error = function() { console.log('required scripts load failed'); }
-            }
-            if (Array.isArray(io[obj].capabilities)) {
-              var requirements_valid = true;
-              for (var test in io[obj].capabilities) {
-                var c = this_awe.capabilities.view(io[obj].capabilities[test])
-                if (!c || !c.value()) {
-                  requirements_valid = false;
-                }
-              }
-              if (requirements_valid) {
-                if (Array.isArray(io[obj].files)) {
-                  _load_file_queue.queue = io[obj].files;
-                  _load_file_queue.success = io[obj].success;
-                  _load_file_queue.error = io[obj].error;
-                  _process_load_file_queue();
-                }
-                else {
-                  _load_file(
-                    'script', 
-                    { src: io[obj].files },
-                    io[obj].success,
-                    io[obj].error
-                  );
-                } 
-                break;
-              }
-            }
-            else {
-              throw 'require is not an array';
-            }
-          }
-        }
-      }
-    }
-
-    function _process_load_file_queue() {
-      var is_loading = _is_loading();
-      if (is_loading.failed) {
-        if (!_load_file_queue.error_called) {
-          _load_file_queue.error_called = true;
-          try {
-            _load_file_queue.error();
-          }
-          catch(e) { /* TODO */ }
-          _load_file_queue = _reset_load_file_queue();
-        }
-        return;
-      }
-      else if (!is_loading.loading) {
-        if (Array.isArray(_load_file_queue.queue) && _load_file_queue.queue.length > 0) {
-          if (Array.isArray(_load_file_queue.queue[0])) {
-            for (var f in _load_file_queue.queue[0]) {
-              var file = _load_file_queue.queue[0][f];
-              _load_file_queue.status[file] = 0
-              _load_file(
-                'script', 
-                { src: file }, 
-                function(e) {
-                  var file = this.getAttribute("src");
-                  _load_file_queue.status[file] = 1;
-                  _process_load_file_queue();
-                },
-                function(e) {
-                  var file = this.getAttribute("src");
-                  _load_file_queue.status[file] = -1;
-                  _process_load_file_queue();
-                }
-              );
-            }
-            _load_file_queue.queue.splice(0, 1);
-          }
-          else {
-            var file = _load_file_queue.queue[0];
-            _load_file_queue.queue.splice(0, 1);
-            _load_file_queue.status[file] = 0;
-            _load_file(
-              'script', 
-              { src: file },
-              function(e) {
-                var file = this.getAttribute("src");
-                _load_file_queue.status[file] = 1;
-                _process_load_file_queue();
-              },
-              function(e) {
-                var file = this.getAttribute("src");
-                _load_file_queue.status[file] = -1;
-                _process_load_file_queue();
-              }
-            );
-          }
-          var is_loading = _is_loading();
-          if (is_loading.failed) {
-            if (!_load_file_queue.error_called) {
-              _load_file_queue.error_called = true;
-              try {
-                _load_file_queue.error();
-              }
-              catch(e) { /* TODO */ }
-              _load_file_queue = _reset_load_file_queue();
-            }
-          }
-        }
-        else {
-          if (!_load_file_queue.success_called) {
-            _load_file_queue.success_called = true;
-            try {
-              _load_file_queue.success();
-            }
-            catch(e) { /* TODO */ }
-            _load_file_queue = _reset_load_file_queue();
-          }
-        }
-      }
-    }
-
-    function _is_loading() {
-      var loading = false;
-      var failed = false;
-      for (var f in _load_file_queue.status) {
-        if (_load_file_queue.status[f] == -1) {
-          failed = true;
-        }
-        else if (_load_file_queue.status[f] == 0) {
-          loading = true;;
-        }
-      }
-      return { loading: loading, failed: failed };
-    }
-
-    function _load_file(type, attributes, success, error) {
-      try {
-        var file = document.createElement(type);
-        for (var i in attributes) {
-          file.setAttribute(i, attributes[i]);
-        }
-        if (success && typeof(success) == 'function') {
-          file.onload = success;
-        }
-        if (error && typeof(error) == 'function') {
-          file.onerror = error;
-        }
-        document.querySelector('head').appendChild(file);
-      }
-      catch(e) { /* TODO */ };
-    }
-    
-    var _get_user_media = undefined, 
-      _connect_stream_to_src = function(){},
-      _stream_targets = {},
-      _disconnect_stream = function(){},
-      _get_stream_targets = function(){
-        return _stream_targets;
-      },
-      _random_id = function(){
-        return 'stream-target-'+Date.now();
-      },
-      _disconnect_stream_timeout;
-      
-    if (navigator.getUserMedia) { // WebRTC 1.0 standard compliant browser
-      _get_user_media = navigator.getUserMedia.bind(navigator);
-      _connect_stream_to_src = function(media_stream, media_element, identifier) {
-        
-        media_element.srcObject = media_stream;
-        media_element.play();
-        if (!identifier) {
-          media_element.setAttribute('data-source-id', '_system');
-        }
-        else {
-          media_element.setAttribute('data-source-id', identifier);
-          _stream_targets[identifier] = {source: media_stream, target: media_element};
-        }
-      };
-    }
-    else if (navigator.mozGetUserMedia) { // early firefox webrtc implementation
-      _get_user_media = navigator.mozGetUserMedia.bind(navigator);
-      _connect_stream_to_src = function(media_stream, media_element, identifier) {
-      
-        media_element.mozSrcObject = media_stream;
-        media_element.play();
-        if (!identifier) {
-          media_element.setAttribute('data-source-id', '_system');
-        }
-        else {
-          media_element.setAttribute('data-source-id', identifier);
-          _stream_targets[identifier] = {source: media_stream, target: media_element};
-        }
-      };
-    }
-    else if (navigator.webkitGetUserMedia) { // early webkit webrtc implementation
-      _get_user_media = navigator.webkitGetUserMedia.bind(navigator);
-      _connect_stream_to_src = function(media_stream, media_element, identifier) {
-        clearTimeout(_disconnect_stream_timeout);
-        media_element.src = URL.createObjectURL(media_stream);
-        if (!identifier) {
-          media_element.setAttribute('data-source-id', '_system');
-          if (Object.keys(_stream_targets).length) {
-            media_element.play();
-          }
-        }
-        else {
-          media_element.setAttribute('data-source-id', identifier);
-          _stream_targets[identifier] = {source: media_stream, target: media_element};
-          media_element.play();
-        }
-      };
-    }
-    _disconnect_stream = function(media_element, identifier){
-      try {
-        media_element.src = '';
-        media_element.pause();
-        
-        if (_stream_targets[identifier]) {
-          delete(_stream_targets[identifier]);
-          
-          if (!Object.keys(_stream_targets).length) {
-            // stop the stream entirely as nothing is listening
-            try {
-              // TODO - add a timeout so we don't turn it on and off multiple times when switching views and multiple items have visibility changed
-              // 1s should be more than enough
-              clearTimeout(_disconnect_stream_timeout);
-              _disconnect_stream_timeout = setTimeout(function(){
-                this_awe.video_streams.delete('default');
-              }, 1000);
-            }
-            catch(e) {
-              console.error('awe.video_streams.delete',e)
-            }
-          }
-        }
-      }
-      catch(e){ console.log('disconnect_stream',e)}
-    };
-
-    function _clean_object(object, list_of_keys) {
-      var keys = {};
-      for (var key in list_of_keys) {
-        keys[list_of_keys[key]] = 1;
-      }
-      for (var key in object) {
-        if (!keys[key]) { 
-          delete object[key];
-        }
-      }
-      return object;
-    }
-    function _extend() {
-			var src, copy, name, options,
-				target = arguments[0] || {},
-				i = 1,
-				length = arguments.length;
-			if (typeof target !== 'object') {
-				target = {};
-			}
-			for (; i < length; i++) {
-				if ((options = arguments[ i ]) !== null) {
-					for (name in options) {
-						src = target[name];
-						copy = options[name];
-						if (src === copy) {
-							continue;
-						}
-						if (copy !== undefined) {
-							target[name] = copy;
-						}
-					}
-				}
-			}
-			return target;
-		}
-		    // https://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/
-    function _type(obj){
-      return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
-    }
-    
-    function _clone_deep(obj) {
-      if (obj === null || typeof obj !== 'object') {
-          return obj;
-      }
-   
-      var temp = obj.constructor(); // give temp the original obj's constructor
-      for (var key in obj) {
-          temp[key] = _clone_deep(obj[key]);
-      }
-   
-      return temp;
-    }
-    
-    function _clone(obj) {
-      if (null == obj || "object" != typeof obj) return obj;
-      var copy = obj.constructor();
-      for (var attr in obj) {
-        if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
-      }
-      return copy;
-    }
-
-    function _get_settings(ids){
-      ids = Array.isArray(ids) ? ids.join('|') : ids;
-      var b = {};
-      if (ids) {
-        b.id = ids
-      };
-      var settings = {};
-      this_awe.settings.list(b).forEach(function(setting){
-        settings[setting.id] = setting.value();
-      });
-      return settings;
-    }
-    function _get_capabilities(ids){
-      ids = Array.isArray(ids) ? ids.join('|') : ids;
-      var b = {};
-      if (ids) {
-        b.id = ids
-      };
-      var capabilities = {};
-      this_awe.capabilities.list(b).forEach(function(capability){
-        capabilities[capability.id] = capability.value();
-      });
-      return capabilities;
-    }
-    var for_each = Function.prototype.call.bind([].forEach);
-		
-    var util = {
-      get_capabilities: _get_capabilities,
-      get_settings: _get_settings,
-      require: _require,
-      get_user_media: _get_user_media,
-      connect_stream_to_src: _connect_stream_to_src,
-      disconnect_stream: _disconnect_stream,
-      get_stream_targets: _get_stream_targets,
-      clean_object: _clean_object,
-      extend: _extend ,
-      clone: _clone,
-      clone_deep: _clone_deep,
-      type: _type,
-      for_each: for_each
-    };
-    
-    
-    window.awe_object = awe_object;
-    window.awe = new awe(); 
-    this_awe = window.awe;
-    this_awe.util = util;
-    
-    this_awe.AUTO_DETECT_DEVICE_TYPE = true;
-  }
-    
-// END FILE:  awe-loader.js file
-
-})(window);
diff --git a/js/awe-standard-dependencies.js b/js/awe-standard-dependencies.js
deleted file mode 100755
index b0f3582..0000000
--- a/js/awe-standard-dependencies.js
+++ /dev/null
@@ -1,5702 +0,0 @@
-/*
-  NOTE: We have combined the minimum collection of required js libs awe depends
-        upon to make it easy for you to get started.
-
-        Please see the relevant URLs listed below for the author and licensing
-        information for each of these files.
-*/
-
-// BEGIN FILE:  Three.js
-// See: https://github.com/mrdoob/three.js/blob/master/src/Three.js
-// threejs.org/license
-(function(l,xa){"object"===typeof exports&&"undefined"!==typeof module?xa(exports):"function"===typeof define&&define.amd?define(["exports"],xa):xa(l.THREE=l.THREE||{})})(this,function(l){function xa(){}function C(a,b){this.x=a||0;this.y=b||0}function ba(a,b,c,d,e,f,g,h,k,m){Object.defineProperty(this,"id",{value:hf++});this.uuid=Y.generateUUID();this.name="";this.image=void 0!==a?a:ba.DEFAULT_IMAGE;this.mipmaps=[];this.mapping=void 0!==b?b:ba.DEFAULT_MAPPING;this.wrapS=void 0!==c?c:1001;this.wrapT=
-void 0!==d?d:1001;this.magFilter=void 0!==e?e:1006;this.minFilter=void 0!==f?f:1008;this.anisotropy=void 0!==k?k:1;this.format=void 0!==g?g:1023;this.type=void 0!==h?h:1009;this.offset=new C(0,0);this.repeat=new C(1,1);this.generateMipmaps=!0;this.premultiplyAlpha=!1;this.flipY=!0;this.unpackAlignment=4;this.encoding=void 0!==m?m:3E3;this.version=0;this.onUpdate=null}function fa(a,b,c,d){this.x=a||0;this.y=b||0;this.z=c||0;this.w=void 0!==d?d:1}function Cb(a,b,c){this.uuid=Y.generateUUID();this.width=
-a;this.height=b;this.scissor=new fa(0,0,a,b);this.scissorTest=!1;this.viewport=new fa(0,0,a,b);c=c||{};void 0===c.minFilter&&(c.minFilter=1006);this.texture=new ba(void 0,void 0,c.wrapS,c.wrapT,c.magFilter,c.minFilter,c.format,c.type,c.anisotropy,c.encoding);this.depthBuffer=void 0!==c.depthBuffer?c.depthBuffer:!0;this.stencilBuffer=void 0!==c.stencilBuffer?c.stencilBuffer:!0;this.depthTexture=void 0!==c.depthTexture?c.depthTexture:null}function Db(a,b,c){Cb.call(this,a,b,c);this.activeMipMapLevel=
-this.activeCubeFace=0}function oa(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._w=void 0!==d?d:1}function n(a,b,c){this.x=a||0;this.y=b||0;this.z=c||0}function K(){this.elements=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1];0<arguments.length&&console.error("THREE.Matrix4: the constructor no longer reads arguments. use .set() instead.")}function db(a,b,c,d,e,f,g,h,k,m,q,v){ba.call(this,null,f,g,h,k,m,d,e,q,v);this.image={data:a,width:b,height:c};this.magFilter=void 0!==k?k:1003;this.minFilter=void 0!==
-m?m:1003;this.flipY=this.generateMipmaps=!1;this.unpackAlignment=1}function Xa(a,b,c,d,e,f,g,h,k,m){a=void 0!==a?a:[];ba.call(this,a,void 0!==b?b:301,c,d,e,f,g,h,k,m);this.flipY=!1}function Eb(a,b,c){var d=a[0];if(0>=d||0<d)return a;var e=b*c,f=xe[e];void 0===f&&(f=new Float32Array(e),xe[e]=f);if(0!==b)for(d.toArray(f,0),d=1,e=0;d!==b;++d)e+=c,a[d].toArray(f,e);return f}function ye(a,b){var c=ze[b];void 0===c&&(c=new Int32Array(b),ze[b]=c);for(var d=0;d!==b;++d)c[d]=a.allocTextureUnit();return c}
-function jf(a,b){a.uniform1f(this.addr,b)}function kf(a,b){a.uniform1i(this.addr,b)}function lf(a,b){void 0===b.x?a.uniform2fv(this.addr,b):a.uniform2f(this.addr,b.x,b.y)}function mf(a,b){void 0!==b.x?a.uniform3f(this.addr,b.x,b.y,b.z):void 0!==b.r?a.uniform3f(this.addr,b.r,b.g,b.b):a.uniform3fv(this.addr,b)}function nf(a,b){void 0===b.x?a.uniform4fv(this.addr,b):a.uniform4f(this.addr,b.x,b.y,b.z,b.w)}function of(a,b){a.uniformMatrix2fv(this.addr,!1,b.elements||b)}function pf(a,b){void 0===b.elements?
-a.uniformMatrix3fv(this.addr,!1,b):(Ae.set(b.elements),a.uniformMatrix3fv(this.addr,!1,Ae))}function qf(a,b){void 0===b.elements?a.uniformMatrix4fv(this.addr,!1,b):(Be.set(b.elements),a.uniformMatrix4fv(this.addr,!1,Be))}function rf(a,b,c){var d=c.allocTextureUnit();a.uniform1i(this.addr,d);c.setTexture2D(b||Ce,d)}function sf(a,b,c){var d=c.allocTextureUnit();a.uniform1i(this.addr,d);c.setTextureCube(b||De,d)}function Ee(a,b){a.uniform2iv(this.addr,b)}function Fe(a,b){a.uniform3iv(this.addr,b)}function Ge(a,
-b){a.uniform4iv(this.addr,b)}function tf(a){switch(a){case 5126:return jf;case 35664:return lf;case 35665:return mf;case 35666:return nf;case 35674:return of;case 35675:return pf;case 35676:return qf;case 35678:case 36198:return rf;case 35680:return sf;case 5124:case 35670:return kf;case 35667:case 35671:return Ee;case 35668:case 35672:return Fe;case 35669:case 35673:return Ge}}function uf(a,b){a.uniform1fv(this.addr,b)}function vf(a,b){a.uniform1iv(this.addr,b)}function wf(a,b){a.uniform2fv(this.addr,
-Eb(b,this.size,2))}function xf(a,b){a.uniform3fv(this.addr,Eb(b,this.size,3))}function yf(a,b){a.uniform4fv(this.addr,Eb(b,this.size,4))}function zf(a,b){a.uniformMatrix2fv(this.addr,!1,Eb(b,this.size,4))}function Af(a,b){a.uniformMatrix3fv(this.addr,!1,Eb(b,this.size,9))}function Bf(a,b){a.uniformMatrix4fv(this.addr,!1,Eb(b,this.size,16))}function Cf(a,b,c){var d=b.length,e=ye(c,d);a.uniform1iv(this.addr,e);for(a=0;a!==d;++a)c.setTexture2D(b[a]||Ce,e[a])}function Df(a,b,c){var d=b.length,e=ye(c,
-d);a.uniform1iv(this.addr,e);for(a=0;a!==d;++a)c.setTextureCube(b[a]||De,e[a])}function Ef(a){switch(a){case 5126:return uf;case 35664:return wf;case 35665:return xf;case 35666:return yf;case 35674:return zf;case 35675:return Af;case 35676:return Bf;case 35678:return Cf;case 35680:return Df;case 5124:case 35670:return vf;case 35667:case 35671:return Ee;case 35668:case 35672:return Fe;case 35669:case 35673:return Ge}}function Ff(a,b,c){this.id=a;this.addr=c;this.setValue=tf(b.type)}function Gf(a,b,
-c){this.id=a;this.addr=c;this.size=b.size;this.setValue=Ef(b.type)}function He(a){this.id=a;this.seq=[];this.map={}}function eb(a,b,c){this.seq=[];this.map={};this.renderer=c;c=a.getProgramParameter(b,a.ACTIVE_UNIFORMS);for(var d=0;d<c;++d){var e=a.getActiveUniform(b,d),f=a.getUniformLocation(b,e.name),g=this,h=e.name,k=h.length;for(Pd.lastIndex=0;;){var m=Pd.exec(h),q=Pd.lastIndex,v=m[1],p=m[3];"]"===m[2]&&(v|=0);if(void 0===p||"["===p&&q+2===k){h=g;e=void 0===p?new Ff(v,e,f):new Gf(v,e,f);h.seq.push(e);
-h.map[e.id]=e;break}else p=g.map[v],void 0===p&&(p=new He(v),v=g,g=p,v.seq.push(g),v.map[g.id]=g),g=p}}}function G(a,b,c){return void 0===b&&void 0===c?this.set(a):this.setRGB(a,b,c)}function fd(a,b){this.min=void 0!==a?a:new C(Infinity,Infinity);this.max=void 0!==b?b:new C(-Infinity,-Infinity)}function Hf(a,b){var c,d,e,f,g,h,k,m,q,v,p=a.context,r=a.state,l,t,y,x,u,H;this.render=function(w,I,W){if(0!==b.length){w=new n;var D=W.w/W.z,O=.5*W.z,aa=.5*W.w,F=16/W.w,ja=new C(F*D,F),T=new n(1,1,0),fb=new C(1,
-1),Ya=new fd;Ya.min.set(W.x,W.y);Ya.max.set(W.x+(W.z-16),W.y+(W.w-16));if(void 0===x){var F=new Float32Array([-1,-1,0,0,1,-1,1,0,1,1,1,1,-1,1,0,1]),ka=new Uint16Array([0,1,2,0,2,3]);l=p.createBuffer();t=p.createBuffer();p.bindBuffer(p.ARRAY_BUFFER,l);p.bufferData(p.ARRAY_BUFFER,F,p.STATIC_DRAW);p.bindBuffer(p.ELEMENT_ARRAY_BUFFER,t);p.bufferData(p.ELEMENT_ARRAY_BUFFER,ka,p.STATIC_DRAW);u=p.createTexture();H=p.createTexture();r.bindTexture(p.TEXTURE_2D,u);p.texImage2D(p.TEXTURE_2D,0,p.RGB,16,16,0,
-p.RGB,p.UNSIGNED_BYTE,null);p.texParameteri(p.TEXTURE_2D,p.TEXTURE_WRAP_S,p.CLAMP_TO_EDGE);p.texParameteri(p.TEXTURE_2D,p.TEXTURE_WRAP_T,p.CLAMP_TO_EDGE);p.texParameteri(p.TEXTURE_2D,p.TEXTURE_MAG_FILTER,p.NEAREST);p.texParameteri(p.TEXTURE_2D,p.TEXTURE_MIN_FILTER,p.NEAREST);r.bindTexture(p.TEXTURE_2D,H);p.texImage2D(p.TEXTURE_2D,0,p.RGBA,16,16,0,p.RGBA,p.UNSIGNED_BYTE,null);p.texParameteri(p.TEXTURE_2D,p.TEXTURE_WRAP_S,p.CLAMP_TO_EDGE);p.texParameteri(p.TEXTURE_2D,p.TEXTURE_WRAP_T,p.CLAMP_TO_EDGE);
-p.texParameteri(p.TEXTURE_2D,p.TEXTURE_MAG_FILTER,p.NEAREST);p.texParameteri(p.TEXTURE_2D,p.TEXTURE_MIN_FILTER,p.NEAREST);var F=y={vertexShader:"uniform lowp int renderType;\nuniform vec3 screenPosition;\nuniform vec2 scale;\nuniform float rotation;\nuniform sampler2D occlusionMap;\nattribute vec2 position;\nattribute vec2 uv;\nvarying vec2 vUV;\nvarying float vVisibility;\nvoid main() {\nvUV = uv;\nvec2 pos = position;\nif ( renderType == 2 ) {\nvec4 visibility = texture2D( occlusionMap, vec2( 0.1, 0.1 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.5, 0.1 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.9, 0.1 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.9, 0.5 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.9, 0.9 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.5, 0.9 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.1, 0.9 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.1, 0.5 ) );\nvisibility += texture2D( occlusionMap, vec2( 0.5, 0.5 ) );\nvVisibility =        visibility.r / 9.0;\nvVisibility *= 1.0 - visibility.g / 9.0;\nvVisibility *=       visibility.b / 9.0;\nvVisibility *= 1.0 - visibility.a / 9.0;\npos.x = cos( rotation ) * position.x - sin( rotation ) * position.y;\npos.y = sin( rotation ) * position.x + cos( rotation ) * position.y;\n}\ngl_Position = vec4( ( pos * scale + screenPosition.xy ).xy, screenPosition.z, 1.0 );\n}",
-fragmentShader:"uniform lowp int renderType;\nuniform sampler2D map;\nuniform float opacity;\nuniform vec3 color;\nvarying vec2 vUV;\nvarying float vVisibility;\nvoid main() {\nif ( renderType == 0 ) {\ngl_FragColor = vec4( 1.0, 0.0, 1.0, 0.0 );\n} else if ( renderType == 1 ) {\ngl_FragColor = texture2D( map, vUV );\n} else {\nvec4 texture = texture2D( map, vUV );\ntexture.a *= opacity * vVisibility;\ngl_FragColor = texture;\ngl_FragColor.rgb *= color;\n}\n}"},ka=p.createProgram(),P=p.createShader(p.FRAGMENT_SHADER),
-M=p.createShader(p.VERTEX_SHADER),V="precision "+a.getPrecision()+" float;\n";p.shaderSource(P,V+F.fragmentShader);p.shaderSource(M,V+F.vertexShader);p.compileShader(P);p.compileShader(M);p.attachShader(ka,P);p.attachShader(ka,M);p.linkProgram(ka);x=ka;q=p.getAttribLocation(x,"position");v=p.getAttribLocation(x,"uv");c=p.getUniformLocation(x,"renderType");d=p.getUniformLocation(x,"map");e=p.getUniformLocation(x,"occlusionMap");f=p.getUniformLocation(x,"opacity");g=p.getUniformLocation(x,"color");
-h=p.getUniformLocation(x,"scale");k=p.getUniformLocation(x,"rotation");m=p.getUniformLocation(x,"screenPosition")}p.useProgram(x);r.initAttributes();r.enableAttribute(q);r.enableAttribute(v);r.disableUnusedAttributes();p.uniform1i(e,0);p.uniform1i(d,1);p.bindBuffer(p.ARRAY_BUFFER,l);p.vertexAttribPointer(q,2,p.FLOAT,!1,16,0);p.vertexAttribPointer(v,2,p.FLOAT,!1,16,8);p.bindBuffer(p.ELEMENT_ARRAY_BUFFER,t);r.disable(p.CULL_FACE);r.buffers.depth.setMask(!1);ka=0;for(P=b.length;ka<P;ka++)if(F=16/W.w,
-ja.set(F*D,F),M=b[ka],w.set(M.matrixWorld.elements[12],M.matrixWorld.elements[13],M.matrixWorld.elements[14]),w.applyMatrix4(I.matrixWorldInverse),w.applyMatrix4(I.projectionMatrix),T.copy(w),fb.x=W.x+T.x*O+O-8,fb.y=W.y+T.y*aa+aa-8,!0===Ya.containsPoint(fb)){r.activeTexture(p.TEXTURE0);r.bindTexture(p.TEXTURE_2D,null);r.activeTexture(p.TEXTURE1);r.bindTexture(p.TEXTURE_2D,u);p.copyTexImage2D(p.TEXTURE_2D,0,p.RGB,fb.x,fb.y,16,16,0);p.uniform1i(c,0);p.uniform2f(h,ja.x,ja.y);p.uniform3f(m,T.x,T.y,T.z);
-r.disable(p.BLEND);r.enable(p.DEPTH_TEST);p.drawElements(p.TRIANGLES,6,p.UNSIGNED_SHORT,0);r.activeTexture(p.TEXTURE0);r.bindTexture(p.TEXTURE_2D,H);p.copyTexImage2D(p.TEXTURE_2D,0,p.RGBA,fb.x,fb.y,16,16,0);p.uniform1i(c,1);r.disable(p.DEPTH_TEST);r.activeTexture(p.TEXTURE1);r.bindTexture(p.TEXTURE_2D,u);p.drawElements(p.TRIANGLES,6,p.UNSIGNED_SHORT,0);M.positionScreen.copy(T);M.customUpdateCallback?M.customUpdateCallback(M):M.updateLensFlares();p.uniform1i(c,2);r.enable(p.BLEND);for(var V=0,pa=M.lensFlares.length;V<
-pa;V++){var S=M.lensFlares[V];.001<S.opacity&&.001<S.scale&&(T.x=S.x,T.y=S.y,T.z=S.z,F=S.size*S.scale/W.w,ja.x=F*D,ja.y=F,p.uniform3f(m,T.x,T.y,T.z),p.uniform2f(h,ja.x,ja.y),p.uniform1f(k,S.rotation),p.uniform1f(f,S.opacity),p.uniform3f(g,S.color.r,S.color.g,S.color.b),r.setBlending(S.blending,S.blendEquation,S.blendSrc,S.blendDst),a.setTexture2D(S.texture,1),p.drawElements(p.TRIANGLES,6,p.UNSIGNED_SHORT,0))}}r.enable(p.CULL_FACE);r.enable(p.DEPTH_TEST);r.buffers.depth.setMask(!0);a.resetGLState()}}}
-function If(a,b){var c,d,e,f,g,h,k,m,q,v,p,r,l,t,y,x,u;function H(a,b){return a.renderOrder!==b.renderOrder?a.renderOrder-b.renderOrder:a.z!==b.z?b.z-a.z:b.id-a.id}var w=a.context,I=a.state,W,D,O,aa,F=new n,ja=new oa,T=new n;this.render=function(n,Ya){if(0!==b.length){if(void 0===O){var ka=new Float32Array([-.5,-.5,0,0,.5,-.5,1,0,.5,.5,1,1,-.5,.5,0,1]),P=new Uint16Array([0,1,2,0,2,3]);W=w.createBuffer();D=w.createBuffer();w.bindBuffer(w.ARRAY_BUFFER,W);w.bufferData(w.ARRAY_BUFFER,ka,w.STATIC_DRAW);
-w.bindBuffer(w.ELEMENT_ARRAY_BUFFER,D);w.bufferData(w.ELEMENT_ARRAY_BUFFER,P,w.STATIC_DRAW);var ka=w.createProgram(),P=w.createShader(w.VERTEX_SHADER),M=w.createShader(w.FRAGMENT_SHADER);w.shaderSource(P,["precision "+a.getPrecision()+" float;","#define SHADER_NAME SpriteMaterial\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform float rotation;\nuniform vec2 scale;\nuniform vec2 uvOffset;\nuniform vec2 uvScale;\nattribute vec2 position;\nattribute vec2 uv;\nvarying vec2 vUV;\nvoid main() {\nvUV = uvOffset + uv * uvScale;\nvec2 alignedPosition = position * scale;\nvec2 rotatedPosition;\nrotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\nrotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\nvec4 finalPosition;\nfinalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\nfinalPosition.xy += rotatedPosition;\nfinalPosition = projectionMatrix * finalPosition;\ngl_Position = finalPosition;\n}"].join("\n"));
-w.shaderSource(M,["precision "+a.getPrecision()+" float;","#define SHADER_NAME SpriteMaterial\nuniform vec3 color;\nuniform sampler2D map;\nuniform float opacity;\nuniform int fogType;\nuniform vec3 fogColor;\nuniform float fogDensity;\nuniform float fogNear;\nuniform float fogFar;\nuniform float alphaTest;\nvarying vec2 vUV;\nvoid main() {\nvec4 texture = texture2D( map, vUV );\nif ( texture.a < alphaTest ) discard;\ngl_FragColor = vec4( color * texture.xyz, texture.a * opacity );\nif ( fogType > 0 ) {\nfloat depth = gl_FragCoord.z / gl_FragCoord.w;\nfloat fogFactor = 0.0;\nif ( fogType == 1 ) {\nfogFactor = smoothstep( fogNear, fogFar, depth );\n} else {\nconst float LOG2 = 1.442695;\nfogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );\nfogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );\n}\ngl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );\n}\n}"].join("\n"));
-w.compileShader(P);w.compileShader(M);w.attachShader(ka,P);w.attachShader(ka,M);w.linkProgram(ka);O=ka;x=w.getAttribLocation(O,"position");u=w.getAttribLocation(O,"uv");c=w.getUniformLocation(O,"uvOffset");d=w.getUniformLocation(O,"uvScale");e=w.getUniformLocation(O,"rotation");f=w.getUniformLocation(O,"scale");g=w.getUniformLocation(O,"color");h=w.getUniformLocation(O,"map");k=w.getUniformLocation(O,"opacity");m=w.getUniformLocation(O,"modelViewMatrix");q=w.getUniformLocation(O,"projectionMatrix");
-v=w.getUniformLocation(O,"fogType");p=w.getUniformLocation(O,"fogDensity");r=w.getUniformLocation(O,"fogNear");l=w.getUniformLocation(O,"fogFar");t=w.getUniformLocation(O,"fogColor");y=w.getUniformLocation(O,"alphaTest");ka=document.createElementNS("http://www.w3.org/1999/xhtml","canvas");ka.width=8;ka.height=8;P=ka.getContext("2d");P.fillStyle="white";P.fillRect(0,0,8,8);aa=new ba(ka);aa.needsUpdate=!0}w.useProgram(O);I.initAttributes();I.enableAttribute(x);I.enableAttribute(u);I.disableUnusedAttributes();
-I.disable(w.CULL_FACE);I.enable(w.BLEND);w.bindBuffer(w.ARRAY_BUFFER,W);w.vertexAttribPointer(x,2,w.FLOAT,!1,16,0);w.vertexAttribPointer(u,2,w.FLOAT,!1,16,8);w.bindBuffer(w.ELEMENT_ARRAY_BUFFER,D);w.uniformMatrix4fv(q,!1,Ya.projectionMatrix.elements);I.activeTexture(w.TEXTURE0);w.uniform1i(h,0);P=ka=0;(M=n.fog)?(w.uniform3f(t,M.color.r,M.color.g,M.color.b),M.isFog?(w.uniform1f(r,M.near),w.uniform1f(l,M.far),w.uniform1i(v,1),P=ka=1):M.isFogExp2&&(w.uniform1f(p,M.density),w.uniform1i(v,2),P=ka=2)):
-(w.uniform1i(v,0),P=ka=0);for(var M=0,V=b.length;M<V;M++){var pa=b[M];pa.modelViewMatrix.multiplyMatrices(Ya.matrixWorldInverse,pa.matrixWorld);pa.z=-pa.modelViewMatrix.elements[14]}b.sort(H);for(var S=[],M=0,V=b.length;M<V;M++){var pa=b[M],N=pa.material;if(!1!==N.visible){pa.onBeforeRender(a,n,Ya,void 0,N,void 0);w.uniform1f(y,N.alphaTest);w.uniformMatrix4fv(m,!1,pa.modelViewMatrix.elements);pa.matrixWorld.decompose(F,ja,T);S[0]=T.x;S[1]=T.y;var C=0;n.fog&&N.fog&&(C=P);ka!==C&&(w.uniform1i(v,C),
-ka=C);null!==N.map?(w.uniform2f(c,N.map.offset.x,N.map.offset.y),w.uniform2f(d,N.map.repeat.x,N.map.repeat.y)):(w.uniform2f(c,0,0),w.uniform2f(d,1,1));w.uniform1f(k,N.opacity);w.uniform3f(g,N.color.r,N.color.g,N.color.b);w.uniform1f(e,N.rotation);w.uniform2fv(f,S);I.setBlending(N.blending,N.blendEquation,N.blendSrc,N.blendDst,N.blendEquationAlpha,N.blendSrcAlpha,N.blendDstAlpha,N.premultipliedAlpha);I.buffers.depth.setTest(N.depthTest);I.buffers.depth.setMask(N.depthWrite);N.map?a.setTexture2D(N.map,
-0):a.setTexture2D(aa,0);w.drawElements(w.TRIANGLES,6,w.UNSIGNED_SHORT,0);pa.onAfterRender(a,n,Ya,void 0,N,void 0)}}I.enable(w.CULL_FACE);a.resetGLState()}}}function U(){Object.defineProperty(this,"id",{value:Jf++});this.uuid=Y.generateUUID();this.name="";this.type="Material";this.lights=this.fog=!0;this.blending=1;this.side=0;this.shading=2;this.vertexColors=0;this.opacity=1;this.transparent=!1;this.blendSrc=204;this.blendDst=205;this.blendEquation=100;this.blendEquationAlpha=this.blendDstAlpha=this.blendSrcAlpha=
-null;this.depthFunc=3;this.depthWrite=this.depthTest=!0;this.clippingPlanes=null;this.clipShadows=this.clipIntersection=!1;this.colorWrite=!0;this.precision=null;this.polygonOffset=!1;this.polygonOffsetUnits=this.polygonOffsetFactor=0;this.dithering=!1;this.alphaTest=0;this.premultipliedAlpha=!1;this.overdraw=0;this.needsUpdate=this.visible=!0}function ra(a){U.call(this);this.type="ShaderMaterial";this.defines={};this.uniforms={};this.vertexShader="void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}";
-this.fragmentShader="void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}";this.linewidth=1;this.wireframe=!1;this.wireframeLinewidth=1;this.morphNormals=this.morphTargets=this.skinning=this.clipping=this.lights=this.fog=!1;this.extensions={derivatives:!1,fragDepth:!1,drawBuffers:!1,shaderTextureLOD:!1};this.defaultAttributeValues={color:[1,1,1],uv:[0,0],uv2:[0,0]};this.index0AttributeName=void 0;void 0!==a&&(void 0!==a.attributes&&console.error("THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead."),
-this.setValues(a))}function Za(a){U.call(this);this.type="MeshDepthMaterial";this.depthPacking=3200;this.morphTargets=this.skinning=!1;this.displacementMap=this.alphaMap=this.map=null;this.displacementScale=1;this.displacementBias=0;this.wireframe=!1;this.wireframeLinewidth=1;this.lights=this.fog=!1;this.setValues(a)}function Ra(a,b){this.min=void 0!==a?a:new n(Infinity,Infinity,Infinity);this.max=void 0!==b?b:new n(-Infinity,-Infinity,-Infinity)}function Ea(a,b){this.center=void 0!==a?a:new n;this.radius=
-void 0!==b?b:0}function Ba(){this.elements=[1,0,0,0,1,0,0,0,1];0<arguments.length&&console.error("THREE.Matrix3: the constructor no longer reads arguments. use .set() instead.")}function Aa(a,b){this.normal=void 0!==a?a:new n(1,0,0);this.constant=void 0!==b?b:0}function gd(a,b,c,d,e,f){this.planes=[void 0!==a?a:new Aa,void 0!==b?b:new Aa,void 0!==c?c:new Aa,void 0!==d?d:new Aa,void 0!==e?e:new Aa,void 0!==f?f:new Aa]}function Ie(a,b,c,d){function e(b,c,d,e){var f=b.geometry,g;g=t;var h=b.customDepthMaterial;
-d&&(g=y,h=b.customDistanceMaterial);h?g=h:(h=!1,c.morphTargets&&(f&&f.isBufferGeometry?h=f.morphAttributes&&f.morphAttributes.position&&0<f.morphAttributes.position.length:f&&f.isGeometry&&(h=f.morphTargets&&0<f.morphTargets.length)),b.isSkinnedMesh&&!1===c.skinning&&console.warn("THREE.WebGLShadowMap: THREE.SkinnedMesh with material.skinning set to false:",b),b=b.isSkinnedMesh&&c.skinning,f=0,h&&(f|=1),b&&(f|=2),g=g[f]);a.localClippingEnabled&&!0===c.clipShadows&&0!==c.clippingPlanes.length&&(f=
-g.uuid,h=c.uuid,b=x[f],void 0===b&&(b={},x[f]=b),f=b[h],void 0===f&&(f=g.clone(),b[h]=f),g=f);g.visible=c.visible;g.wireframe=c.wireframe;h=c.side;F.renderSingleSided&&2==h&&(h=0);F.renderReverseSided&&(0===h?h=1:1===h&&(h=0));g.side=h;g.clipShadows=c.clipShadows;g.clippingPlanes=c.clippingPlanes;g.wireframeLinewidth=c.wireframeLinewidth;g.linewidth=c.linewidth;d&&void 0!==g.uniforms.lightPos&&g.uniforms.lightPos.value.copy(e);return g}function f(b,d,g,h){if(!1!==b.visible){if(b.layers.test(d.layers)&&
-(b.isMesh||b.isLine||b.isPoints)&&b.castShadow&&(!b.frustumCulled||k.intersectsObject(b))){b.modelViewMatrix.multiplyMatrices(g.matrixWorldInverse,b.matrixWorld);var m=c.update(b),p=b.material;if(Array.isArray(p))for(var q=m.groups,v=0,r=q.length;v<r;v++){var u=q[v],w=p[u.materialIndex];w&&w.visible&&(w=e(b,w,h,l),a.renderBufferDirect(g,null,m,w,b,u))}else p.visible&&(w=e(b,p,h,l),a.renderBufferDirect(g,null,m,w,b,null))}b=b.children;m=0;for(p=b.length;m<p;m++)f(b[m],d,g,h)}}var g=a.context,h=a.state,
-k=new gd,m=new K,q=b.shadows,v=new C,p=new C(d.maxTextureSize,d.maxTextureSize),r=new n,l=new n,t=Array(4),y=Array(4),x={},u=[new n(1,0,0),new n(-1,0,0),new n(0,0,1),new n(0,0,-1),new n(0,1,0),new n(0,-1,0)],H=[new n(0,1,0),new n(0,1,0),new n(0,1,0),new n(0,1,0),new n(0,0,1),new n(0,0,-1)],w=[new fa,new fa,new fa,new fa,new fa,new fa];b=new Za;b.depthPacking=3201;b.clipping=!0;d=$a.distanceRGBA;for(var I=Ca.clone(d.uniforms),W=0;4!==W;++W){var D=0!==(W&1),O=0!==(W&2),aa=b.clone();aa.morphTargets=
-D;aa.skinning=O;t[W]=aa;D=new ra({defines:{USE_SHADOWMAP:""},uniforms:I,vertexShader:d.vertexShader,fragmentShader:d.fragmentShader,morphTargets:D,skinning:O,clipping:!0});y[W]=D}var F=this;this.enabled=!1;this.autoUpdate=!0;this.needsUpdate=!1;this.type=1;this.renderSingleSided=this.renderReverseSided=!0;this.render=function(b,c){if(!1!==F.enabled&&(!1!==F.autoUpdate||!1!==F.needsUpdate)&&0!==q.length){h.disable(g.BLEND);h.buffers.color.setClear(1,1,1,1);h.buffers.depth.setTest(!0);h.setScissorTest(!1);
-for(var d,e=0,t=q.length;e<t;e++){var n=q[e];d=n.shadow;var y=n&&n.isPointLight;if(void 0===d)console.warn("THREE.WebGLShadowMap:",n,"has no shadow.");else{var x=d.camera;v.copy(d.mapSize);v.min(p);if(y){var D=v.x,I=v.y;w[0].set(2*D,I,D,I);w[1].set(0,I,D,I);w[2].set(3*D,I,D,I);w[3].set(D,I,D,I);w[4].set(3*D,0,D,I);w[5].set(D,0,D,I);v.x*=4;v.y*=2}null===d.map&&(d.map=new Cb(v.x,v.y,{minFilter:1003,magFilter:1003,format:1023}),d.map.texture.name=n.name+".shadowMap",x.updateProjectionMatrix());d.isSpotLightShadow&&
-d.update(n);D=d.map;I=d.matrix;l.setFromMatrixPosition(n.matrixWorld);x.position.copy(l);y?(d=6,I.makeTranslation(-l.x,-l.y,-l.z)):(d=1,r.setFromMatrixPosition(n.target.matrixWorld),x.lookAt(r),x.updateMatrixWorld(),I.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1),I.multiply(x.projectionMatrix),I.multiply(x.matrixWorldInverse));a.setRenderTarget(D);a.clear();for(n=0;n<d;n++)y&&(r.copy(x.position),r.add(u[n]),x.up.copy(H[n]),x.lookAt(r),x.updateMatrixWorld(),h.viewport(w[n])),m.multiplyMatrices(x.projectionMatrix,
-x.matrixWorldInverse),k.setFromMatrix(m),f(b,c,x,y)}}e=a.getClearColor();t=a.getClearAlpha();a.setClearColor(e,t);F.needsUpdate=!1}}}function Kf(a){var b={};return{get:function(a){a.isInterleavedBufferAttribute&&(a=a.data);return b[a.uuid]},remove:function(c){c.isInterleavedBufferAttribute&&(c=c.data);var d=b[c.uuid];d&&(a.deleteBuffer(d.buffer),delete b[c.uuid])},update:function(c,d){c.isInterleavedBufferAttribute&&(c=c.data);var e=b[c.uuid];if(void 0===e){var e=c.uuid,f=c,g=f.array,h=f.dynamic?
-a.DYNAMIC_DRAW:a.STATIC_DRAW,k=a.createBuffer();a.bindBuffer(d,k);a.bufferData(d,g,h);f.onUploadCallback();h=a.FLOAT;g instanceof Float32Array?h=a.FLOAT:g instanceof Float64Array?console.warn("THREE.WebGLAttributes: Unsupported data buffer format: Float64Array."):g instanceof Uint16Array?h=a.UNSIGNED_SHORT:g instanceof Int16Array?h=a.SHORT:g instanceof Uint32Array?h=a.UNSIGNED_INT:g instanceof Int32Array?h=a.INT:g instanceof Int8Array?h=a.BYTE:g instanceof Uint8Array&&(h=a.UNSIGNED_BYTE);b[e]={buffer:k,
-type:h,bytesPerElement:g.BYTES_PER_ELEMENT,version:f.version}}else e.version<c.version&&(f=c,g=f.array,k=f.updateRange,a.bindBuffer(d,e.buffer),!1===f.dynamic?a.bufferData(d,g,a.STATIC_DRAW):-1===k.count?a.bufferSubData(d,0,g):0===k.count?console.error("THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually."):(a.bufferSubData(d,k.offset*g.BYTES_PER_ELEMENT,g.subarray(k.offset,k.offset+
-k.count)),k.count=-1),e.version=c.version)}}}function ab(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._order=d||ab.DefaultOrder}function Qd(){this.mask=1}function z(){Object.defineProperty(this,"id",{value:Lf++});this.uuid=Y.generateUUID();this.name="";this.type="Object3D";this.parent=null;this.children=[];this.up=z.DefaultUp.clone();var a=new n,b=new ab,c=new oa,d=new n(1,1,1);b.onChange(function(){c.setFromEuler(b,!1)});c.onChange(function(){b.setFromQuaternion(c,void 0,!1)});Object.defineProperties(this,
-{position:{enumerable:!0,value:a},rotation:{enumerable:!0,value:b},quaternion:{enumerable:!0,value:c},scale:{enumerable:!0,value:d},modelViewMatrix:{value:new K},normalMatrix:{value:new Ba}});this.matrix=new K;this.matrixWorld=new K;this.matrixAutoUpdate=z.DefaultMatrixAutoUpdate;this.matrixWorldNeedsUpdate=!1;this.layers=new Qd;this.visible=!0;this.receiveShadow=this.castShadow=!1;this.frustumCulled=!0;this.renderOrder=0;this.userData={}}function Na(){z.call(this);this.type="Camera";this.matrixWorldInverse=
-new K;this.projectionMatrix=new K}function Fb(a,b,c,d,e,f){Na.call(this);this.type="OrthographicCamera";this.zoom=1;this.view=null;this.left=a;this.right=b;this.top=c;this.bottom=d;this.near=void 0!==e?e:.1;this.far=void 0!==f?f:2E3;this.updateProjectionMatrix()}function qa(a,b,c,d){Na.call(this);this.type="PerspectiveCamera";this.fov=void 0!==a?a:50;this.zoom=1;this.near=void 0!==c?c:.1;this.far=void 0!==d?d:2E3;this.focus=10;this.aspect=void 0!==b?b:1;this.view=null;this.filmGauge=35;this.filmOffset=
-0;this.updateProjectionMatrix()}function Sa(a,b,c,d,e,f){this.a=a;this.b=b;this.c=c;this.normal=d&&d.isVector3?d:new n;this.vertexNormals=Array.isArray(d)?d:[];this.color=e&&e.isColor?e:new G;this.vertexColors=Array.isArray(e)?e:[];this.materialIndex=void 0!==f?f:0}function J(){Object.defineProperty(this,"id",{value:Rd++});this.uuid=Y.generateUUID();this.name="";this.type="Geometry";this.vertices=[];this.colors=[];this.faces=[];this.faceVertexUvs=[[]];this.morphTargets=[];this.morphNormals=[];this.skinWeights=
-[];this.skinIndices=[];this.lineDistances=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate=this.lineDistancesNeedUpdate=this.colorsNeedUpdate=this.normalsNeedUpdate=this.uvsNeedUpdate=this.verticesNeedUpdate=this.elementsNeedUpdate=!1}function Z(a,b,c){if(Array.isArray(a))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.uuid=Y.generateUUID();this.name="";this.array=a;this.itemSize=b;this.count=void 0!==a?a.length/b:0;this.normalized=!0===c;this.dynamic=
-!1;this.updateRange={offset:0,count:-1};this.onUploadCallback=function(){};this.version=0}function pc(a,b){Z.call(this,new Int8Array(a),b)}function qc(a,b){Z.call(this,new Uint8Array(a),b)}function rc(a,b){Z.call(this,new Uint8ClampedArray(a),b)}function sc(a,b){Z.call(this,new Int16Array(a),b)}function gb(a,b){Z.call(this,new Uint16Array(a),b)}function tc(a,b){Z.call(this,new Int32Array(a),b)}function hb(a,b){Z.call(this,new Uint32Array(a),b)}function B(a,b){Z.call(this,new Float32Array(a),b)}function uc(a,
-b){Z.call(this,new Float64Array(a),b)}function Je(){this.indices=[];this.vertices=[];this.normals=[];this.colors=[];this.uvs=[];this.uvs2=[];this.groups=[];this.morphTargets={};this.skinWeights=[];this.skinIndices=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate=this.uvsNeedUpdate=this.colorsNeedUpdate=this.normalsNeedUpdate=this.verticesNeedUpdate=!1}function Sd(a){if(0===a.length)return-Infinity;for(var b=a[0],c=1,d=a.length;c<d;++c)a[c]>b&&(b=a[c]);return b}function E(){Object.defineProperty(this,
-"id",{value:Rd++});this.uuid=Y.generateUUID();this.name="";this.type="BufferGeometry";this.index=null;this.attributes={};this.morphAttributes={};this.groups=[];this.boundingSphere=this.boundingBox=null;this.drawRange={start:0,count:Infinity}}function Gb(a,b,c,d,e,f){J.call(this);this.type="BoxGeometry";this.parameters={width:a,height:b,depth:c,widthSegments:d,heightSegments:e,depthSegments:f};this.fromBufferGeometry(new ib(a,b,c,d,e,f));this.mergeVertices()}function ib(a,b,c,d,e,f){function g(a,b,
-c,d,e,f,g,l,W,D,O){var aa=f/W,F=g/D,ja=f/2,T=g/2,C=l/2;g=W+1;var B=D+1,z=f=0,P,M,V=new n;for(M=0;M<B;M++){var pa=M*F-T;for(P=0;P<g;P++)V[a]=(P*aa-ja)*d,V[b]=pa*e,V[c]=C,m.push(V.x,V.y,V.z),V[a]=0,V[b]=0,V[c]=0<l?1:-1,q.push(V.x,V.y,V.z),v.push(P/W),v.push(1-M/D),f+=1}for(M=0;M<D;M++)for(P=0;P<W;P++)a=p+P+g*(M+1),b=p+(P+1)+g*(M+1),c=p+(P+1)+g*M,k.push(p+P+g*M,a,c),k.push(a,b,c),z+=6;h.addGroup(r,z,O);r+=z;p+=f}E.call(this);this.type="BoxBufferGeometry";this.parameters={width:a,height:b,depth:c,widthSegments:d,
-heightSegments:e,depthSegments:f};var h=this;d=Math.floor(d)||1;e=Math.floor(e)||1;f=Math.floor(f)||1;var k=[],m=[],q=[],v=[],p=0,r=0;g("z","y","x",-1,-1,c,b,a,f,e,0);g("z","y","x",1,-1,c,b,-a,f,e,1);g("x","z","y",1,1,a,c,b,d,f,2);g("x","z","y",1,-1,a,c,-b,d,f,3);g("x","y","z",1,-1,a,b,c,d,e,4);g("x","y","z",-1,-1,a,b,-c,d,e,5);this.setIndex(k);this.addAttribute("position",new B(m,3));this.addAttribute("normal",new B(q,3));this.addAttribute("uv",new B(v,2))}function vc(a,b,c,d){J.call(this);this.type=
-"PlaneGeometry";this.parameters={width:a,height:b,widthSegments:c,heightSegments:d};this.fromBufferGeometry(new jb(a,b,c,d));this.mergeVertices()}function jb(a,b,c,d){E.call(this);this.type="PlaneBufferGeometry";this.parameters={width:a,height:b,widthSegments:c,heightSegments:d};var e=a/2,f=b/2;c=Math.floor(c)||1;d=Math.floor(d)||1;var g=c+1,h=d+1,k=a/c,m=b/d,q=[],v=[],p=[],r=[];for(a=0;a<h;a++){var l=a*m-f;for(b=0;b<g;b++)v.push(b*k-e,-l,0),p.push(0,0,1),r.push(b/c),r.push(1-a/d)}for(a=0;a<d;a++)for(b=
-0;b<c;b++)e=b+g*(a+1),f=b+1+g*(a+1),h=b+1+g*a,q.push(b+g*a,e,h),q.push(e,f,h);this.setIndex(q);this.addAttribute("position",new B(v,3));this.addAttribute("normal",new B(p,3));this.addAttribute("uv",new B(r,2))}function ya(a){U.call(this);this.type="MeshBasicMaterial";this.color=new G(16777215);this.lightMap=this.map=null;this.lightMapIntensity=1;this.aoMap=null;this.aoMapIntensity=1;this.envMap=this.alphaMap=this.specularMap=null;this.combine=0;this.reflectivity=1;this.refractionRatio=.98;this.wireframe=
-!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap="round";this.lights=this.morphTargets=this.skinning=!1;this.setValues(a)}function kb(a,b){this.origin=void 0!==a?a:new n;this.direction=void 0!==b?b:new n}function Hb(a,b){this.start=void 0!==a?a:new n;this.end=void 0!==b?b:new n}function Ta(a,b,c){this.a=void 0!==a?a:new n;this.b=void 0!==b?b:new n;this.c=void 0!==c?c:new n}function la(a,b){z.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new E;this.material=void 0!==
-b?b:new ya({color:16777215*Math.random()});this.drawMode=0;this.updateMorphTargets()}function Mf(a,b,c,d){function e(a,c){b.buffers.color.setClear(a.r,a.g,a.b,c,d)}var f=new G(0),g=0,h,k,m,q;return{getClearColor:function(){return f},setClearColor:function(a,b){f.set(a);g=void 0!==b?b:1;e(f,g)},getClearAlpha:function(){return g},setClearAlpha:function(a){g=a;e(f,g)},render:function(b,d,r){b=b.background;null===b?e(f,g):b&&b.isColor&&(e(b,1),r=!0);(a.autoClear||r)&&a.clear(a.autoClearColor,a.autoClearDepth,
-a.autoClearStencil);b&&b.isCubeTexture?(void 0===m&&(m=new qa,q=new la(new ib(5,5,5),new ra({uniforms:$a.cube.uniforms,vertexShader:$a.cube.vertexShader,fragmentShader:$a.cube.fragmentShader,side:1,depthTest:!1,depthWrite:!1,fog:!1}))),m.projectionMatrix.copy(d.projectionMatrix),m.matrixWorld.extractRotation(d.matrixWorld),m.matrixWorldInverse.getInverse(m.matrixWorld),q.material.uniforms.tCube.value=b,q.modelViewMatrix.multiplyMatrices(m.matrixWorldInverse,q.matrixWorld),c.update(q),a.renderBufferDirect(m,
-null,q.geometry,q.material,q,null)):b&&b.isTexture&&(void 0===h&&(h=new Fb(-1,1,1,-1,0,1),k=new la(new jb(2,2),new ya({depthTest:!1,depthWrite:!1,fog:!1}))),k.material.map=b,c.update(k),a.renderBufferDirect(h,null,k.geometry,k.material,k,null))}}}function Nf(a,b){return a.renderOrder!==b.renderOrder?a.renderOrder-b.renderOrder:a.program&&b.program&&a.program!==b.program?a.program.id-b.program.id:a.material.id!==b.material.id?a.material.id-b.material.id:a.z!==b.z?a.z-b.z:a.id-b.id}function Of(a,b){return a.renderOrder!==
-b.renderOrder?a.renderOrder-b.renderOrder:a.z!==b.z?b.z-a.z:a.id-b.id}function Pf(){var a=[],b=-1,c=[],d=-1;return{opaque:a,transparent:c,init:function(){d=b=-1},push:function(e,f,g,h,k){var m,q;g.transparent?(m=c,q=++d):(m=a,q=++b);(q=m[q])?(q.id=e.id,q.object=e,q.geometry=f,q.material=g,q.program=g.program,q.renderOrder=e.renderOrder,q.z=h,q.group=k):(q={id:e.id,object:e,geometry:f,material:g,program:g.program,renderOrder:e.renderOrder,z:h,group:k},m.push(q))},finish:function(){a.length=b+1;c.length=
-d+1},sort:function(){a.sort(Nf);c.sort(Of)}}}function Qf(){var a={};return{get:function(b,c){var d=b.id+","+c.id,e=a[d];void 0===e&&(e=new Pf,a[d]=e);return e},dispose:function(){a={}}}}function Rf(a,b,c){var d,e,f;this.setMode=function(a){d=a};this.setIndex=function(a){e=a.type;f=a.bytesPerElement};this.render=function(b,h){a.drawElements(d,h,e,b*f);c.calls++;c.vertices+=h;d===a.TRIANGLES&&(c.faces+=h/3)};this.renderInstances=function(g,h,k){var m=b.get("ANGLE_instanced_arrays");null===m?console.error("THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays."):
-(m.drawElementsInstancedANGLE(d,k,e,h*f,g.maxInstancedCount),c.calls++,c.vertices+=k*g.maxInstancedCount,d===a.TRIANGLES&&(c.faces+=g.maxInstancedCount*k/3))}}function Sf(a,b,c){var d;this.setMode=function(a){d=a};this.render=function(b,f){a.drawArrays(d,b,f);c.calls++;c.vertices+=f;d===a.TRIANGLES&&(c.faces+=f/3)};this.renderInstances=function(e,f,g){var h=b.get("ANGLE_instanced_arrays");if(null===h)console.error("THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.");
-else{var k=e.attributes.position;k.isInterleavedBufferAttribute?(g=k.data.count,h.drawArraysInstancedANGLE(d,0,g,e.maxInstancedCount)):h.drawArraysInstancedANGLE(d,f,g,e.maxInstancedCount);c.calls++;c.vertices+=g*e.maxInstancedCount;d===a.TRIANGLES&&(c.faces+=e.maxInstancedCount*g/3)}}}function Tf(a,b,c){function d(a){a=a.target;var h=e[a.id];null!==h.index&&b.remove(h.index);for(var k in h.attributes)b.remove(h.attributes[k]);a.removeEventListener("dispose",d);delete e[a.id];if(k=f[a.id])b.remove(k),
-delete f[a.id];if(k=f[h.id])b.remove(k),delete f[h.id];c.geometries--}var e={},f={};return{get:function(a,b){var f=e[b.id];if(f)return f;b.addEventListener("dispose",d);b.isBufferGeometry?f=b:b.isGeometry&&(void 0===b._bufferGeometry&&(b._bufferGeometry=(new E).setFromObject(a)),f=b._bufferGeometry);e[b.id]=f;c.geometries++;return f},update:function(c){var d=c.index,e=c.attributes;null!==d&&b.update(d,a.ELEMENT_ARRAY_BUFFER);for(var f in e)b.update(e[f],a.ARRAY_BUFFER);c=c.morphAttributes;for(f in c)for(var d=
-c[f],e=0,q=d.length;e<q;e++)b.update(d[e],a.ARRAY_BUFFER)},getWireframeAttribute:function(c){var d=f[c.id];if(d)return d;var d=[],e=c.index,m=c.attributes;if(null!==e)for(var e=e.array,m=0,q=e.length;m<q;m+=3){var v=e[m+0],p=e[m+1],r=e[m+2];d.push(v,p,p,r,r,v)}else for(e=m.position.array,m=0,q=e.length/3-1;m<q;m+=3)v=m+0,p=m+1,r=m+2,d.push(v,p,p,r,r,v);d=new (65535<Sd(d)?hb:gb)(d,1);b.update(d,a.ELEMENT_ARRAY_BUFFER);return f[c.id]=d}}}function Uf(){var a={};return{get:function(b){if(void 0!==a[b.id])return a[b.id];
-var c;switch(b.type){case "DirectionalLight":c={direction:new n,color:new G,shadow:!1,shadowBias:0,shadowRadius:1,shadowMapSize:new C};break;case "SpotLight":c={position:new n,direction:new n,color:new G,distance:0,coneCos:0,penumbraCos:0,decay:0,shadow:!1,shadowBias:0,shadowRadius:1,shadowMapSize:new C};break;case "PointLight":c={position:new n,color:new G,distance:0,decay:0,shadow:!1,shadowBias:0,shadowRadius:1,shadowMapSize:new C};break;case "HemisphereLight":c={direction:new n,skyColor:new G,
-groundColor:new G};break;case "RectAreaLight":c={color:new G,position:new n,halfWidth:new n,halfHeight:new n}}return a[b.id]=c}}}function Vf(a,b,c){var d={};return{update:function(a){var f=c.frame,g=a.geometry,h=b.get(a,g);d[h.id]!==f&&(g.isGeometry&&h.updateFromObject(a),b.update(h),d[h.id]=f);return h},clear:function(){d={}}}}function Wf(a){a=a.split("\n");for(var b=0;b<a.length;b++)a[b]=b+1+": "+a[b];return a.join("\n")}function Ke(a,b,c){var d=a.createShader(b);a.shaderSource(d,c);a.compileShader(d);
-!1===a.getShaderParameter(d,a.COMPILE_STATUS)&&console.error("THREE.WebGLShader: Shader couldn't compile.");""!==a.getShaderInfoLog(d)&&console.warn("THREE.WebGLShader: gl.getShaderInfoLog()",b===a.VERTEX_SHADER?"vertex":"fragment",a.getShaderInfoLog(d),Wf(c));return d}function Le(a){switch(a){case 3E3:return["Linear","( value )"];case 3001:return["sRGB","( value )"];case 3002:return["RGBE","( value )"];case 3004:return["RGBM","( value, 7.0 )"];case 3005:return["RGBM","( value, 16.0 )"];case 3006:return["RGBD",
-"( value, 256.0 )"];case 3007:return["Gamma","( value, float( GAMMA_FACTOR ) )"];default:throw Error("unsupported encoding: "+a);}}function Td(a,b){var c=Le(b);return"vec4 "+a+"( vec4 value ) { return "+c[0]+"ToLinear"+c[1]+"; }"}function Xf(a,b){var c=Le(b);return"vec4 "+a+"( vec4 value ) { return LinearTo"+c[0]+c[1]+"; }"}function Yf(a,b){var c;switch(b){case 1:c="Linear";break;case 2:c="Reinhard";break;case 3:c="Uncharted2";break;case 4:c="OptimizedCineon";break;default:throw Error("unsupported toneMapping: "+
-b);}return"vec3 "+a+"( vec3 color ) { return "+c+"ToneMapping( color ); }"}function Zf(a,b,c){a=a||{};return[a.derivatives||b.envMapCubeUV||b.bumpMap||b.normalMap||b.flatShading?"#extension GL_OES_standard_derivatives : enable":"",(a.fragDepth||b.logarithmicDepthBuffer)&&c.get("EXT_frag_depth")?"#extension GL_EXT_frag_depth : enable":"",a.drawBuffers&&c.get("WEBGL_draw_buffers")?"#extension GL_EXT_draw_buffers : require":"",(a.shaderTextureLOD||b.envMap)&&c.get("EXT_shader_texture_lod")?"#extension GL_EXT_shader_texture_lod : enable":
-""].filter(wc).join("\n")}function $f(a){var b=[],c;for(c in a){var d=a[c];!1!==d&&b.push("#define "+c+" "+d)}return b.join("\n")}function wc(a){return""!==a}function Me(a,b){return a.replace(/NUM_DIR_LIGHTS/g,b.numDirLights).replace(/NUM_SPOT_LIGHTS/g,b.numSpotLights).replace(/NUM_RECT_AREA_LIGHTS/g,b.numRectAreaLights).replace(/NUM_POINT_LIGHTS/g,b.numPointLights).replace(/NUM_HEMI_LIGHTS/g,b.numHemiLights)}function Ud(a){return a.replace(/^[ \t]*#include +<([\w\d.]+)>/gm,function(a,c){var d=X[c];
-if(void 0===d)throw Error("Can not resolve #include <"+c+">");return Ud(d)})}function Ne(a){return a.replace(/for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g,function(a,c,d,e){a="";for(c=parseInt(c);c<parseInt(d);c++)a+=e.replace(/\[ i \]/g,"[ "+c+" ]");return a})}function ag(a,b,c,d,e){var f=a.context,g=c.extensions,h=c.defines,k=d.vertexShader,m=d.fragmentShader,q="SHADOWMAP_TYPE_BASIC";1===e.shadowMapType?q="SHADOWMAP_TYPE_PCF":2===e.shadowMapType&&(q="SHADOWMAP_TYPE_PCF_SOFT");
-var v="ENVMAP_TYPE_CUBE",p="ENVMAP_MODE_REFLECTION",r="ENVMAP_BLENDING_MULTIPLY";if(e.envMap){switch(c.envMap.mapping){case 301:case 302:v="ENVMAP_TYPE_CUBE";break;case 306:case 307:v="ENVMAP_TYPE_CUBE_UV";break;case 303:case 304:v="ENVMAP_TYPE_EQUIREC";break;case 305:v="ENVMAP_TYPE_SPHERE"}switch(c.envMap.mapping){case 302:case 304:p="ENVMAP_MODE_REFRACTION"}switch(c.combine){case 0:r="ENVMAP_BLENDING_MULTIPLY";break;case 1:r="ENVMAP_BLENDING_MIX";break;case 2:r="ENVMAP_BLENDING_ADD"}}var l=0<a.gammaFactor?
-a.gammaFactor:1,g=Zf(g,e,a.extensions),t=$f(h),n=f.createProgram();c.isRawShaderMaterial?(h=[t,"\n"].filter(wc).join("\n"),d=[g,t,"\n"].filter(wc).join("\n")):(h=["precision "+e.precision+" float;","precision "+e.precision+" int;","#define SHADER_NAME "+d.name,t,e.supportsVertexTextures?"#define VERTEX_TEXTURES":"","#define GAMMA_FACTOR "+l,"#define MAX_BONES "+e.maxBones,e.useFog&&e.fog?"#define USE_FOG":"",e.useFog&&e.fogExp?"#define FOG_EXP2":"",e.map?"#define USE_MAP":"",e.envMap?"#define USE_ENVMAP":
-"",e.envMap?"#define "+p:"",e.lightMap?"#define USE_LIGHTMAP":"",e.aoMap?"#define USE_AOMAP":"",e.emissiveMap?"#define USE_EMISSIVEMAP":"",e.bumpMap?"#define USE_BUMPMAP":"",e.normalMap?"#define USE_NORMALMAP":"",e.displacementMap&&e.supportsVertexTextures?"#define USE_DISPLACEMENTMAP":"",e.specularMap?"#define USE_SPECULARMAP":"",e.roughnessMap?"#define USE_ROUGHNESSMAP":"",e.metalnessMap?"#define USE_METALNESSMAP":"",e.alphaMap?"#define USE_ALPHAMAP":"",e.vertexColors?"#define USE_COLOR":"",e.flatShading?
-"#define FLAT_SHADED":"",e.skinning?"#define USE_SKINNING":"",e.useVertexTexture?"#define BONE_TEXTURE":"",e.morphTargets?"#define USE_MORPHTARGETS":"",e.morphNormals&&!1===e.flatShading?"#define USE_MORPHNORMALS":"",e.doubleSided?"#define DOUBLE_SIDED":"",e.flipSided?"#define FLIP_SIDED":"","#define NUM_CLIPPING_PLANES "+e.numClippingPlanes,e.shadowMapEnabled?"#define USE_SHADOWMAP":"",e.shadowMapEnabled?"#define "+q:"",e.sizeAttenuation?"#define USE_SIZEATTENUATION":"",e.logarithmicDepthBuffer?
-"#define USE_LOGDEPTHBUF":"",e.logarithmicDepthBuffer&&a.extensions.get("EXT_frag_depth")?"#define USE_LOGDEPTHBUF_EXT":"","uniform mat4 modelMatrix;","uniform mat4 modelViewMatrix;","uniform mat4 projectionMatrix;","uniform mat4 viewMatrix;","uniform mat3 normalMatrix;","uniform vec3 cameraPosition;","attribute vec3 position;","attribute vec3 normal;","attribute vec2 uv;","#ifdef USE_COLOR","\tattribute vec3 color;","#endif","#ifdef USE_MORPHTARGETS","\tattribute vec3 morphTarget0;","\tattribute vec3 morphTarget1;",
-"\tattribute vec3 morphTarget2;","\tattribute vec3 morphTarget3;","\t#ifdef USE_MORPHNORMALS","\t\tattribute vec3 morphNormal0;","\t\tattribute vec3 morphNormal1;","\t\tattribute vec3 morphNormal2;","\t\tattribute vec3 morphNormal3;","\t#else","\t\tattribute vec3 morphTarget4;","\t\tattribute vec3 morphTarget5;","\t\tattribute vec3 morphTarget6;","\t\tattribute vec3 morphTarget7;","\t#endif","#endif","#ifdef USE_SKINNING","\tattribute vec4 skinIndex;","\tattribute vec4 skinWeight;","#endif","\n"].filter(wc).join("\n"),
-d=[g,"precision "+e.precision+" float;","precision "+e.precision+" int;","#define SHADER_NAME "+d.name,t,e.alphaTest?"#define ALPHATEST "+e.alphaTest:"","#define GAMMA_FACTOR "+l,e.useFog&&e.fog?"#define USE_FOG":"",e.useFog&&e.fogExp?"#define FOG_EXP2":"",e.map?"#define USE_MAP":"",e.envMap?"#define USE_ENVMAP":"",e.envMap?"#define "+v:"",e.envMap?"#define "+p:"",e.envMap?"#define "+r:"",e.lightMap?"#define USE_LIGHTMAP":"",e.aoMap?"#define USE_AOMAP":"",e.emissiveMap?"#define USE_EMISSIVEMAP":"",
-e.bumpMap?"#define USE_BUMPMAP":"",e.normalMap?"#define USE_NORMALMAP":"",e.specularMap?"#define USE_SPECULARMAP":"",e.roughnessMap?"#define USE_ROUGHNESSMAP":"",e.metalnessMap?"#define USE_METALNESSMAP":"",e.alphaMap?"#define USE_ALPHAMAP":"",e.vertexColors?"#define USE_COLOR":"",e.gradientMap?"#define USE_GRADIENTMAP":"",e.flatShading?"#define FLAT_SHADED":"",e.doubleSided?"#define DOUBLE_SIDED":"",e.flipSided?"#define FLIP_SIDED":"","#define NUM_CLIPPING_PLANES "+e.numClippingPlanes,"#define UNION_CLIPPING_PLANES "+
-(e.numClippingPlanes-e.numClipIntersection),e.shadowMapEnabled?"#define USE_SHADOWMAP":"",e.shadowMapEnabled?"#define "+q:"",e.premultipliedAlpha?"#define PREMULTIPLIED_ALPHA":"",e.physicallyCorrectLights?"#define PHYSICALLY_CORRECT_LIGHTS":"",e.logarithmicDepthBuffer?"#define USE_LOGDEPTHBUF":"",e.logarithmicDepthBuffer&&a.extensions.get("EXT_frag_depth")?"#define USE_LOGDEPTHBUF_EXT":"",e.envMap&&a.extensions.get("EXT_shader_texture_lod")?"#define TEXTURE_LOD_EXT":"","uniform mat4 viewMatrix;",
-"uniform vec3 cameraPosition;",0!==e.toneMapping?"#define TONE_MAPPING":"",0!==e.toneMapping?X.tonemapping_pars_fragment:"",0!==e.toneMapping?Yf("toneMapping",e.toneMapping):"",e.dithering?"#define DITHERING":"",e.outputEncoding||e.mapEncoding||e.envMapEncoding||e.emissiveMapEncoding?X.encodings_pars_fragment:"",e.mapEncoding?Td("mapTexelToLinear",e.mapEncoding):"",e.envMapEncoding?Td("envMapTexelToLinear",e.envMapEncoding):"",e.emissiveMapEncoding?Td("emissiveMapTexelToLinear",e.emissiveMapEncoding):
-"",e.outputEncoding?Xf("linearToOutputTexel",e.outputEncoding):"",e.depthPacking?"#define DEPTH_PACKING "+c.depthPacking:"","\n"].filter(wc).join("\n"));k=Ud(k);k=Me(k,e);m=Ud(m);m=Me(m,e);c.isShaderMaterial||(k=Ne(k),m=Ne(m));m=d+m;k=Ke(f,f.VERTEX_SHADER,h+k);m=Ke(f,f.FRAGMENT_SHADER,m);f.attachShader(n,k);f.attachShader(n,m);void 0!==c.index0AttributeName?f.bindAttribLocation(n,0,c.index0AttributeName):!0===e.morphTargets&&f.bindAttribLocation(n,0,"position");f.linkProgram(n);e=f.getProgramInfoLog(n);
-q=f.getShaderInfoLog(k);v=f.getShaderInfoLog(m);r=p=!0;if(!1===f.getProgramParameter(n,f.LINK_STATUS))p=!1,console.error("THREE.WebGLProgram: shader error: ",f.getError(),"gl.VALIDATE_STATUS",f.getProgramParameter(n,f.VALIDATE_STATUS),"gl.getProgramInfoLog",e,q,v);else if(""!==e)console.warn("THREE.WebGLProgram: gl.getProgramInfoLog()",e);else if(""===q||""===v)r=!1;r&&(this.diagnostics={runnable:p,material:c,programLog:e,vertexShader:{log:q,prefix:h},fragmentShader:{log:v,prefix:d}});f.deleteShader(k);
-f.deleteShader(m);var x;this.getUniforms=function(){void 0===x&&(x=new eb(f,n,a));return x};var u;this.getAttributes=function(){if(void 0===u){for(var a={},b=f.getProgramParameter(n,f.ACTIVE_ATTRIBUTES),c=0;c<b;c++){var d=f.getActiveAttrib(n,c).name;a[d]=f.getAttribLocation(n,d)}u=a}return u};this.destroy=function(){f.deleteProgram(n);this.program=void 0};Object.defineProperties(this,{uniforms:{get:function(){console.warn("THREE.WebGLProgram: .uniforms is now .getUniforms().");return this.getUniforms()}},
-attributes:{get:function(){console.warn("THREE.WebGLProgram: .attributes is now .getAttributes().");return this.getAttributes()}}});this.id=bg++;this.code=b;this.usedTimes=1;this.program=n;this.vertexShader=k;this.fragmentShader=m;return this}function cg(a,b){function c(a,b){var c;a?a.isTexture?c=a.encoding:a.isWebGLRenderTarget&&(console.warn("THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead."),c=a.texture.encoding):c=3E3;3E3===
-c&&b&&(c=3007);return c}var d=[],e={MeshDepthMaterial:"depth",MeshNormalMaterial:"normal",MeshBasicMaterial:"basic",MeshLambertMaterial:"lambert",MeshPhongMaterial:"phong",MeshToonMaterial:"phong",MeshStandardMaterial:"physical",MeshPhysicalMaterial:"physical",LineBasicMaterial:"basic",LineDashedMaterial:"dashed",PointsMaterial:"points"},f="precision supportsVertexTextures map mapEncoding envMap envMapMode envMapEncoding lightMap aoMap emissiveMap emissiveMapEncoding bumpMap normalMap displacementMap specularMap roughnessMap metalnessMap gradientMap alphaMap combine vertexColors fog useFog fogExp flatShading sizeAttenuation logarithmicDepthBuffer skinning maxBones useVertexTexture morphTargets morphNormals maxMorphTargets maxMorphNormals premultipliedAlpha numDirLights numPointLights numSpotLights numHemiLights numRectAreaLights shadowMapEnabled shadowMapType toneMapping physicallyCorrectLights alphaTest doubleSided flipSided numClippingPlanes numClipIntersection depthPacking dithering".split(" ");
-this.getParameters=function(d,f,k,m,q,v){var p=e[d.type],r;if(v.isSkinnedMesh)if(r=v.skeleton.bones,b.floatVertexTextures)r=1024;else{var l=Math.min(Math.floor((b.maxVertexUniforms-20)/4),r.length);l<r.length?(console.warn("THREE.WebGLRenderer: Skeleton has "+r.length+" bones. This GPU supports "+l+"."),r=0):r=l}else r=0;l=a.getPrecision();null!==d.precision&&(l=b.getMaxPrecision(d.precision),l!==d.precision&&console.warn("THREE.WebGLProgram.getParameters:",d.precision,"not supported, using",l,"instead."));
-var t=a.getRenderTarget();return{shaderID:p,precision:l,supportsVertexTextures:b.vertexTextures,outputEncoding:c(t?t.texture:null,a.gammaOutput),map:!!d.map,mapEncoding:c(d.map,a.gammaInput),envMap:!!d.envMap,envMapMode:d.envMap&&d.envMap.mapping,envMapEncoding:c(d.envMap,a.gammaInput),envMapCubeUV:!!d.envMap&&(306===d.envMap.mapping||307===d.envMap.mapping),lightMap:!!d.lightMap,aoMap:!!d.aoMap,emissiveMap:!!d.emissiveMap,emissiveMapEncoding:c(d.emissiveMap,a.gammaInput),bumpMap:!!d.bumpMap,normalMap:!!d.normalMap,
-displacementMap:!!d.displacementMap,roughnessMap:!!d.roughnessMap,metalnessMap:!!d.metalnessMap,specularMap:!!d.specularMap,alphaMap:!!d.alphaMap,gradientMap:!!d.gradientMap,combine:d.combine,vertexColors:d.vertexColors,fog:!!k,useFog:d.fog,fogExp:k&&k.isFogExp2,flatShading:1===d.shading,sizeAttenuation:d.sizeAttenuation,logarithmicDepthBuffer:b.logarithmicDepthBuffer,skinning:d.skinning&&0<r,maxBones:r,useVertexTexture:b.floatVertexTextures,morphTargets:d.morphTargets,morphNormals:d.morphNormals,
-maxMorphTargets:a.maxMorphTargets,maxMorphNormals:a.maxMorphNormals,numDirLights:f.directional.length,numPointLights:f.point.length,numSpotLights:f.spot.length,numRectAreaLights:f.rectArea.length,numHemiLights:f.hemi.length,numClippingPlanes:m,numClipIntersection:q,dithering:d.dithering,shadowMapEnabled:a.shadowMap.enabled&&v.receiveShadow&&0<f.shadows.length,shadowMapType:a.shadowMap.type,toneMapping:a.toneMapping,physicallyCorrectLights:a.physicallyCorrectLights,premultipliedAlpha:d.premultipliedAlpha,
-alphaTest:d.alphaTest,doubleSided:2===d.side,flipSided:1===d.side,depthPacking:void 0!==d.depthPacking?d.depthPacking:!1}};this.getProgramCode=function(b,c){var d=[];c.shaderID?d.push(c.shaderID):(d.push(b.fragmentShader),d.push(b.vertexShader));if(void 0!==b.defines)for(var e in b.defines)d.push(e),d.push(b.defines[e]);for(e=0;e<f.length;e++)d.push(c[f[e]]);d.push(b.onBeforeCompile.toString());d.push(a.gammaOutput);return d.join()};this.acquireProgram=function(b,c,e,f){for(var q,v=0,p=d.length;v<
-p;v++){var r=d[v];if(r.code===f){q=r;++q.usedTimes;break}}void 0===q&&(q=new ag(a,f,b,c,e),d.push(q));return q};this.releaseProgram=function(a){if(0===--a.usedTimes){var b=d.indexOf(a);d[b]=d[d.length-1];d.pop();a.destroy()}};this.programs=d}function dg(a,b,c,d,e,f,g){function h(a,b){if(a.width>b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElementNS("http://www.w3.org/1999/xhtml","canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,
-0,0,a.width,a.height,0,0,d.width,d.height);console.warn("THREE.WebGLRenderer: image is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height,a);return d}return a}function k(a){return Y.isPowerOfTwo(a.width)&&Y.isPowerOfTwo(a.height)}function m(a,b){return a.generateMipmaps&&b&&1003!==a.minFilter&&1006!==a.minFilter}function q(b){return 1003===b||1004===b||1005===b?a.NEAREST:a.LINEAR}function v(b){b=b.target;b.removeEventListener("dispose",v);a:{var c=d.get(b);if(b.image&&c.__image__webglTextureCube)a.deleteTexture(c.__image__webglTextureCube);
-else{if(void 0===c.__webglInit)break a;a.deleteTexture(c.__webglTexture)}d.remove(b)}g.textures--}function p(b){b=b.target;b.removeEventListener("dispose",p);var c=d.get(b),e=d.get(b.texture);if(b){void 0!==e.__webglTexture&&a.deleteTexture(e.__webglTexture);b.depthTexture&&b.depthTexture.dispose();if(b.isWebGLRenderTargetCube)for(e=0;6>e;e++)a.deleteFramebuffer(c.__webglFramebuffer[e]),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer[e]);else a.deleteFramebuffer(c.__webglFramebuffer),
-c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer);d.remove(b.texture);d.remove(b)}g.textures--}function r(b,p){var q=d.get(b);if(0<b.version&&q.__version!==b.version){var r=b.image;if(void 0===r)console.warn("THREE.WebGLRenderer: Texture marked for update but image is undefined",b);else if(!1===r.complete)console.warn("THREE.WebGLRenderer: Texture marked for update but image is incomplete",b);else{void 0===q.__webglInit&&(q.__webglInit=!0,b.addEventListener("dispose",v),q.__webglTexture=
-a.createTexture(),g.textures++);c.activeTexture(a.TEXTURE0+p);c.bindTexture(a.TEXTURE_2D,q.__webglTexture);a.pixelStorei(a.UNPACK_FLIP_Y_WEBGL,b.flipY);a.pixelStorei(a.UNPACK_PREMULTIPLY_ALPHA_WEBGL,b.premultiplyAlpha);a.pixelStorei(a.UNPACK_ALIGNMENT,b.unpackAlignment);var t=h(b.image,e.maxTextureSize);if((1001!==b.wrapS||1001!==b.wrapT||1003!==b.minFilter&&1006!==b.minFilter)&&!1===k(t))if(r=t,r instanceof HTMLImageElement||r instanceof HTMLCanvasElement){var n=document.createElementNS("http://www.w3.org/1999/xhtml",
-"canvas");n.width=Y.nearestPowerOfTwo(r.width);n.height=Y.nearestPowerOfTwo(r.height);n.getContext("2d").drawImage(r,0,0,n.width,n.height);console.warn("THREE.WebGLRenderer: image is not power of two ("+r.width+"x"+r.height+"). Resized to "+n.width+"x"+n.height,r);t=n}else t=r;var r=k(t),n=f(b.format),y=f(b.type);l(a.TEXTURE_2D,b,r);var aa=b.mipmaps;if(b.isDepthTexture){aa=a.DEPTH_COMPONENT;if(1015===b.type){if(!x)throw Error("Float Depth Texture only supported in WebGL2.0");aa=a.DEPTH_COMPONENT32F}else x&&
-(aa=a.DEPTH_COMPONENT16);1026===b.format&&aa===a.DEPTH_COMPONENT&&1012!==b.type&&1014!==b.type&&(console.warn("THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture."),b.type=1012,y=f(b.type));1027===b.format&&(aa=a.DEPTH_STENCIL,1020!==b.type&&(console.warn("THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture."),b.type=1020,y=f(b.type)));c.texImage2D(a.TEXTURE_2D,0,aa,t.width,t.height,0,n,y,null)}else if(b.isDataTexture)if(0<aa.length&&
-r){for(var F=0,ja=aa.length;F<ja;F++)t=aa[F],c.texImage2D(a.TEXTURE_2D,F,n,t.width,t.height,0,n,y,t.data);b.generateMipmaps=!1}else c.texImage2D(a.TEXTURE_2D,0,n,t.width,t.height,0,n,y,t.data);else if(b.isCompressedTexture)for(F=0,ja=aa.length;F<ja;F++)t=aa[F],1023!==b.format&&1022!==b.format?-1<c.getCompressedTextureFormats().indexOf(n)?c.compressedTexImage2D(a.TEXTURE_2D,F,n,t.width,t.height,0,t.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()"):
-c.texImage2D(a.TEXTURE_2D,F,n,t.width,t.height,0,n,y,t.data);else if(0<aa.length&&r){F=0;for(ja=aa.length;F<ja;F++)t=aa[F],c.texImage2D(a.TEXTURE_2D,F,n,n,y,t);b.generateMipmaps=!1}else c.texImage2D(a.TEXTURE_2D,0,n,n,y,t);m(b,r)&&a.generateMipmap(a.TEXTURE_2D);q.__version=b.version;if(b.onUpdate)b.onUpdate(b);return}}c.activeTexture(a.TEXTURE0+p);c.bindTexture(a.TEXTURE_2D,q.__webglTexture)}function l(c,g,h){h?(a.texParameteri(c,a.TEXTURE_WRAP_S,f(g.wrapS)),a.texParameteri(c,a.TEXTURE_WRAP_T,f(g.wrapT)),
-a.texParameteri(c,a.TEXTURE_MAG_FILTER,f(g.magFilter)),a.texParameteri(c,a.TEXTURE_MIN_FILTER,f(g.minFilter))):(a.texParameteri(c,a.TEXTURE_WRAP_S,a.CLAMP_TO_EDGE),a.texParameteri(c,a.TEXTURE_WRAP_T,a.CLAMP_TO_EDGE),1001===g.wrapS&&1001===g.wrapT||console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.",g),a.texParameteri(c,a.TEXTURE_MAG_FILTER,q(g.magFilter)),a.texParameteri(c,a.TEXTURE_MIN_FILTER,q(g.minFilter)),
-1003!==g.minFilter&&1006!==g.minFilter&&console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.",g));!(h=b.get("EXT_texture_filter_anisotropic"))||1015===g.type&&null===b.get("OES_texture_float_linear")||1016===g.type&&null===b.get("OES_texture_half_float_linear")||!(1<g.anisotropy||d.get(g).__currentAnisotropy)||(a.texParameterf(c,h.TEXTURE_MAX_ANISOTROPY_EXT,Math.min(g.anisotropy,e.getMaxAnisotropy())),d.get(g).__currentAnisotropy=
-g.anisotropy)}function t(b,e,g,h){var k=f(e.texture.format),m=f(e.texture.type);c.texImage2D(h,0,k,e.width,e.height,0,k,m,null);a.bindFramebuffer(a.FRAMEBUFFER,b);a.framebufferTexture2D(a.FRAMEBUFFER,g,h,d.get(e.texture).__webglTexture,0);a.bindFramebuffer(a.FRAMEBUFFER,null)}function n(b,c){a.bindRenderbuffer(a.RENDERBUFFER,b);c.depthBuffer&&!c.stencilBuffer?(a.renderbufferStorage(a.RENDERBUFFER,a.DEPTH_COMPONENT16,c.width,c.height),a.framebufferRenderbuffer(a.FRAMEBUFFER,a.DEPTH_ATTACHMENT,a.RENDERBUFFER,
-b)):c.depthBuffer&&c.stencilBuffer?(a.renderbufferStorage(a.RENDERBUFFER,a.DEPTH_STENCIL,c.width,c.height),a.framebufferRenderbuffer(a.FRAMEBUFFER,a.DEPTH_STENCIL_ATTACHMENT,a.RENDERBUFFER,b)):a.renderbufferStorage(a.RENDERBUFFER,a.RGBA4,c.width,c.height);a.bindRenderbuffer(a.RENDERBUFFER,null)}var x="undefined"!==typeof WebGL2RenderingContext&&a instanceof WebGL2RenderingContext;this.setTexture2D=r;this.setTextureCube=function(b,p){var q=d.get(b);if(6===b.image.length)if(0<b.version&&q.__version!==
-b.version){q.__image__webglTextureCube||(b.addEventListener("dispose",v),q.__image__webglTextureCube=a.createTexture(),g.textures++);c.activeTexture(a.TEXTURE0+p);c.bindTexture(a.TEXTURE_CUBE_MAP,q.__image__webglTextureCube);a.pixelStorei(a.UNPACK_FLIP_Y_WEBGL,b.flipY);for(var r=b&&b.isCompressedTexture,t=b.image[0]&&b.image[0].isDataTexture,n=[],y=0;6>y;y++)n[y]=r||t?t?b.image[y].image:b.image[y]:h(b.image[y],e.maxCubemapSize);var x=k(n[0]),F=f(b.format),ja=f(b.type);l(a.TEXTURE_CUBE_MAP,b,x);for(y=
-0;6>y;y++)if(r)for(var T,C=n[y].mipmaps,z=0,B=C.length;z<B;z++)T=C[z],1023!==b.format&&1022!==b.format?-1<c.getCompressedTextureFormats().indexOf(F)?c.compressedTexImage2D(a.TEXTURE_CUBE_MAP_POSITIVE_X+y,z,F,T.width,T.height,0,T.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()"):c.texImage2D(a.TEXTURE_CUBE_MAP_POSITIVE_X+y,z,F,T.width,T.height,0,F,ja,T.data);else t?c.texImage2D(a.TEXTURE_CUBE_MAP_POSITIVE_X+y,0,F,n[y].width,n[y].height,
-0,F,ja,n[y].data):c.texImage2D(a.TEXTURE_CUBE_MAP_POSITIVE_X+y,0,F,F,ja,n[y]);m(b,x)&&a.generateMipmap(a.TEXTURE_CUBE_MAP);q.__version=b.version;if(b.onUpdate)b.onUpdate(b)}else c.activeTexture(a.TEXTURE0+p),c.bindTexture(a.TEXTURE_CUBE_MAP,q.__image__webglTextureCube)};this.setTextureCubeDynamic=function(b,e){c.activeTexture(a.TEXTURE0+e);c.bindTexture(a.TEXTURE_CUBE_MAP,d.get(b).__webglTexture)};this.setupRenderTarget=function(b){var e=d.get(b),f=d.get(b.texture);b.addEventListener("dispose",p);
-f.__webglTexture=a.createTexture();g.textures++;var h=!0===b.isWebGLRenderTargetCube,q=k(b);if(h){e.__webglFramebuffer=[];for(var v=0;6>v;v++)e.__webglFramebuffer[v]=a.createFramebuffer()}else e.__webglFramebuffer=a.createFramebuffer();if(h){c.bindTexture(a.TEXTURE_CUBE_MAP,f.__webglTexture);l(a.TEXTURE_CUBE_MAP,b.texture,q);for(v=0;6>v;v++)t(e.__webglFramebuffer[v],b,a.COLOR_ATTACHMENT0,a.TEXTURE_CUBE_MAP_POSITIVE_X+v);m(b.texture,q)&&a.generateMipmap(a.TEXTURE_CUBE_MAP);c.bindTexture(a.TEXTURE_CUBE_MAP,
-null)}else c.bindTexture(a.TEXTURE_2D,f.__webglTexture),l(a.TEXTURE_2D,b.texture,q),t(e.__webglFramebuffer,b,a.COLOR_ATTACHMENT0,a.TEXTURE_2D),m(b.texture,q)&&a.generateMipmap(a.TEXTURE_2D),c.bindTexture(a.TEXTURE_2D,null);if(b.depthBuffer){e=d.get(b);f=!0===b.isWebGLRenderTargetCube;if(b.depthTexture){if(f)throw Error("target.depthTexture not supported in Cube render targets");if(b&&b.isWebGLRenderTargetCube)throw Error("Depth Texture with cube render targets is not supported!");a.bindFramebuffer(a.FRAMEBUFFER,
-e.__webglFramebuffer);if(!b.depthTexture||!b.depthTexture.isDepthTexture)throw Error("renderTarget.depthTexture must be an instance of THREE.DepthTexture");d.get(b.depthTexture).__webglTexture&&b.depthTexture.image.width===b.width&&b.depthTexture.image.height===b.height||(b.depthTexture.image.width=b.width,b.depthTexture.image.height=b.height,b.depthTexture.needsUpdate=!0);r(b.depthTexture,0);e=d.get(b.depthTexture).__webglTexture;if(1026===b.depthTexture.format)a.framebufferTexture2D(a.FRAMEBUFFER,
-a.DEPTH_ATTACHMENT,a.TEXTURE_2D,e,0);else if(1027===b.depthTexture.format)a.framebufferTexture2D(a.FRAMEBUFFER,a.DEPTH_STENCIL_ATTACHMENT,a.TEXTURE_2D,e,0);else throw Error("Unknown depthTexture format");}else if(f)for(e.__webglDepthbuffer=[],f=0;6>f;f++)a.bindFramebuffer(a.FRAMEBUFFER,e.__webglFramebuffer[f]),e.__webglDepthbuffer[f]=a.createRenderbuffer(),n(e.__webglDepthbuffer[f],b);else a.bindFramebuffer(a.FRAMEBUFFER,e.__webglFramebuffer),e.__webglDepthbuffer=a.createRenderbuffer(),n(e.__webglDepthbuffer,
-b);a.bindFramebuffer(a.FRAMEBUFFER,null)}};this.updateRenderTargetMipmap=function(b){var e=b.texture,f=k(b);m(e,f)&&(b=b.isWebGLRenderTargetCube?a.TEXTURE_CUBE_MAP:a.TEXTURE_2D,e=d.get(e).__webglTexture,c.bindTexture(b,e),a.generateMipmap(b),c.bindTexture(b,null))}}function eg(){var a={};return{get:function(b){b=b.uuid;var c=a[b];void 0===c&&(c={},a[b]=c);return c},remove:function(b){delete a[b.uuid]},clear:function(){a={}}}}function fg(a,b,c){function d(b,c,d){var e=new Uint8Array(4),f=a.createTexture();
-a.bindTexture(b,f);a.texParameteri(b,a.TEXTURE_MIN_FILTER,a.NEAREST);a.texParameteri(b,a.TEXTURE_MAG_FILTER,a.NEAREST);for(b=0;b<d;b++)a.texImage2D(c+b,0,a.RGBA,1,1,0,a.RGBA,a.UNSIGNED_BYTE,e);return f}function e(b){!0!==u[b]&&(a.enable(b),u[b]=!0)}function f(b){!1!==u[b]&&(a.disable(b),u[b]=!1)}function g(b,d,g,h,k,m,p,q){0!==b?e(a.BLEND):f(a.BLEND);5===b||b===w&&q===ja||(2===b?q?(a.blendEquationSeparate(a.FUNC_ADD,a.FUNC_ADD),a.blendFuncSeparate(a.ONE,a.ONE,a.ONE,a.ONE)):(a.blendEquation(a.FUNC_ADD),
-a.blendFunc(a.SRC_ALPHA,a.ONE)):3===b?q?(a.blendEquationSeparate(a.FUNC_ADD,a.FUNC_ADD),a.blendFuncSeparate(a.ZERO,a.ZERO,a.ONE_MINUS_SRC_COLOR,a.ONE_MINUS_SRC_ALPHA)):(a.blendEquation(a.FUNC_ADD),a.blendFunc(a.ZERO,a.ONE_MINUS_SRC_COLOR)):4===b?q?(a.blendEquationSeparate(a.FUNC_ADD,a.FUNC_ADD),a.blendFuncSeparate(a.ZERO,a.SRC_COLOR,a.ZERO,a.SRC_ALPHA)):(a.blendEquation(a.FUNC_ADD),a.blendFunc(a.ZERO,a.SRC_COLOR)):q?(a.blendEquationSeparate(a.FUNC_ADD,a.FUNC_ADD),a.blendFuncSeparate(a.ONE,a.ONE_MINUS_SRC_ALPHA,
-a.ONE,a.ONE_MINUS_SRC_ALPHA)):(a.blendEquationSeparate(a.FUNC_ADD,a.FUNC_ADD),a.blendFuncSeparate(a.SRC_ALPHA,a.ONE_MINUS_SRC_ALPHA,a.ONE,a.ONE_MINUS_SRC_ALPHA)),w=b,ja=q);if(5===b){k=k||d;m=m||g;p=p||h;if(d!==I||k!==O)a.blendEquationSeparate(c(d),c(k)),I=d,O=k;if(g!==W||h!==D||m!==aa||p!==F)a.blendFuncSeparate(c(g),c(h),c(m),c(p)),W=g,D=h,aa=m,F=p}else F=aa=O=D=W=I=null}function h(b){T!==b&&(b?a.frontFace(a.CW):a.frontFace(a.CCW),T=b)}function k(b){0!==b?(e(a.CULL_FACE),b!==C&&(1===b?a.cullFace(a.BACK):
-2===b?a.cullFace(a.FRONT):a.cullFace(a.FRONT_AND_BACK))):f(a.CULL_FACE);C=b}function m(b,c,d){if(b){if(e(a.POLYGON_OFFSET_FILL),B!==c||P!==d)a.polygonOffset(c,d),B=c,P=d}else f(a.POLYGON_OFFSET_FILL)}function q(b){void 0===b&&(b=a.TEXTURE0+V-1);S!==b&&(a.activeTexture(b),S=b)}var v=new function(){var b=!1,c=new fa,d=null,e=new fa;return{setMask:function(c){d===c||b||(a.colorMask(c,c,c,c),d=c)},setLocked:function(a){b=a},setClear:function(b,d,f,g,h){!0===h&&(b*=g,d*=g,f*=g);c.set(b,d,f,g);!1===e.equals(c)&&
-(a.clearColor(b,d,f,g),e.copy(c))},reset:function(){b=!1;d=null;e.set(0,0,0,1)}}},p=new function(){var b=!1,c=null,d=null,g=null;return{setTest:function(b){b?e(a.DEPTH_TEST):f(a.DEPTH_TEST)},setMask:function(d){c===d||b||(a.depthMask(d),c=d)},setFunc:function(b){if(d!==b){if(b)switch(b){case 0:a.depthFunc(a.NEVER);break;case 1:a.depthFunc(a.ALWAYS);break;case 2:a.depthFunc(a.LESS);break;case 3:a.depthFunc(a.LEQUAL);break;case 4:a.depthFunc(a.EQUAL);break;case 5:a.depthFunc(a.GEQUAL);break;case 6:a.depthFunc(a.GREATER);
-break;case 7:a.depthFunc(a.NOTEQUAL);break;default:a.depthFunc(a.LEQUAL)}else a.depthFunc(a.LEQUAL);d=b}},setLocked:function(a){b=a},setClear:function(b){g!==b&&(a.clearDepth(b),g=b)},reset:function(){b=!1;g=d=c=null}}},r=new function(){var b=!1,c=null,d=null,g=null,h=null,k=null,m=null,p=null,q=null;return{setTest:function(b){b?e(a.STENCIL_TEST):f(a.STENCIL_TEST)},setMask:function(d){c===d||b||(a.stencilMask(d),c=d)},setFunc:function(b,c,e){if(d!==b||g!==c||h!==e)a.stencilFunc(b,c,e),d=b,g=c,h=e},
-setOp:function(b,c,d){if(k!==b||m!==c||p!==d)a.stencilOp(b,c,d),k=b,m=c,p=d},setLocked:function(a){b=a},setClear:function(b){q!==b&&(a.clearStencil(b),q=b)},reset:function(){b=!1;q=p=m=k=h=g=d=c=null}}},l=a.getParameter(a.MAX_VERTEX_ATTRIBS),t=new Uint8Array(l),n=new Uint8Array(l),x=new Uint8Array(l),u={},H=null,w=null,I=null,W=null,D=null,O=null,aa=null,F=null,ja=!1,T=null,C=null,z=null,B=null,P=null,M=null,V=a.getParameter(a.MAX_COMBINED_TEXTURE_IMAGE_UNITS),l=parseFloat(/^WebGL\ ([0-9])/.exec(a.getParameter(a.VERSION))[1]),
-pa=1<=parseFloat(l),S=null,N={},E=new fa,G=new fa,K={};K[a.TEXTURE_2D]=d(a.TEXTURE_2D,a.TEXTURE_2D,1);K[a.TEXTURE_CUBE_MAP]=d(a.TEXTURE_CUBE_MAP,a.TEXTURE_CUBE_MAP_POSITIVE_X,6);return{buffers:{color:v,depth:p,stencil:r},init:function(){v.setClear(0,0,0,1);p.setClear(1);r.setClear(0);e(a.DEPTH_TEST);p.setFunc(3);h(!1);k(1);e(a.CULL_FACE);e(a.BLEND);g(1)},initAttributes:function(){for(var a=0,b=t.length;a<b;a++)t[a]=0},enableAttribute:function(c){t[c]=1;0===n[c]&&(a.enableVertexAttribArray(c),n[c]=
-1);0!==x[c]&&(b.get("ANGLE_instanced_arrays").vertexAttribDivisorANGLE(c,0),x[c]=0)},enableAttributeAndDivisor:function(c,d){t[c]=1;0===n[c]&&(a.enableVertexAttribArray(c),n[c]=1);x[c]!==d&&(b.get("ANGLE_instanced_arrays").vertexAttribDivisorANGLE(c,d),x[c]=d)},disableUnusedAttributes:function(){for(var b=0,c=n.length;b!==c;++b)n[b]!==t[b]&&(a.disableVertexAttribArray(b),n[b]=0)},enable:e,disable:f,getCompressedTextureFormats:function(){if(null===H&&(H=[],b.get("WEBGL_compressed_texture_pvrtc")||
-b.get("WEBGL_compressed_texture_s3tc")||b.get("WEBGL_compressed_texture_etc1")))for(var c=a.getParameter(a.COMPRESSED_TEXTURE_FORMATS),d=0;d<c.length;d++)H.push(c[d]);return H},setBlending:g,setMaterial:function(b){2===b.side?f(a.CULL_FACE):e(a.CULL_FACE);h(1===b.side);!0===b.transparent?g(b.blending,b.blendEquation,b.blendSrc,b.blendDst,b.blendEquationAlpha,b.blendSrcAlpha,b.blendDstAlpha,b.premultipliedAlpha):g(0);p.setFunc(b.depthFunc);p.setTest(b.depthTest);p.setMask(b.depthWrite);v.setMask(b.colorWrite);
-m(b.polygonOffset,b.polygonOffsetFactor,b.polygonOffsetUnits)},setFlipSided:h,setCullFace:k,setLineWidth:function(b){b!==z&&(pa&&a.lineWidth(b),z=b)},setPolygonOffset:m,getScissorTest:function(){return M},setScissorTest:function(b){(M=b)?e(a.SCISSOR_TEST):f(a.SCISSOR_TEST)},activeTexture:q,bindTexture:function(b,c){null===S&&q();var d=N[S];void 0===d&&(d={type:void 0,texture:void 0},N[S]=d);if(d.type!==b||d.texture!==c)a.bindTexture(b,c||K[b]),d.type=b,d.texture=c},compressedTexImage2D:function(){try{a.compressedTexImage2D.apply(a,
-arguments)}catch(b){console.error("THREE.WebGLState:",b)}},texImage2D:function(){try{a.texImage2D.apply(a,arguments)}catch(b){console.error("THREE.WebGLState:",b)}},scissor:function(b){!1===E.equals(b)&&(a.scissor(b.x,b.y,b.z,b.w),E.copy(b))},viewport:function(b){!1===G.equals(b)&&(a.viewport(b.x,b.y,b.z,b.w),G.copy(b))},reset:function(){for(var b=0;b<n.length;b++)1===n[b]&&(a.disableVertexAttribArray(b),n[b]=0);u={};S=H=null;N={};C=T=w=null;v.reset();p.reset();r.reset()}}}function gg(a,b,c){function d(b){if("highp"===
-b){if(0<a.getShaderPrecisionFormat(a.VERTEX_SHADER,a.HIGH_FLOAT).precision&&0<a.getShaderPrecisionFormat(a.FRAGMENT_SHADER,a.HIGH_FLOAT).precision)return"highp";b="mediump"}return"mediump"===b&&0<a.getShaderPrecisionFormat(a.VERTEX_SHADER,a.MEDIUM_FLOAT).precision&&0<a.getShaderPrecisionFormat(a.FRAGMENT_SHADER,a.MEDIUM_FLOAT).precision?"mediump":"lowp"}var e,f=void 0!==c.precision?c.precision:"highp",g=d(f);g!==f&&(console.warn("THREE.WebGLRenderer:",f,"not supported, using",g,"instead."),f=g);c=
-!0===c.logarithmicDepthBuffer&&!!b.get("EXT_frag_depth");var g=a.getParameter(a.MAX_TEXTURE_IMAGE_UNITS),h=a.getParameter(a.MAX_VERTEX_TEXTURE_IMAGE_UNITS),k=a.getParameter(a.MAX_TEXTURE_SIZE),m=a.getParameter(a.MAX_CUBE_MAP_TEXTURE_SIZE),q=a.getParameter(a.MAX_VERTEX_ATTRIBS),v=a.getParameter(a.MAX_VERTEX_UNIFORM_VECTORS),p=a.getParameter(a.MAX_VARYING_VECTORS),r=a.getParameter(a.MAX_FRAGMENT_UNIFORM_VECTORS),l=0<h,t=!!b.get("OES_texture_float");return{getMaxAnisotropy:function(){if(void 0!==e)return e;
-var c=b.get("EXT_texture_filter_anisotropic");return e=null!==c?a.getParameter(c.MAX_TEXTURE_MAX_ANISOTROPY_EXT):0},getMaxPrecision:d,precision:f,logarithmicDepthBuffer:c,maxTextures:g,maxVertexTextures:h,maxTextureSize:k,maxCubemapSize:m,maxAttributes:q,maxVertexUniforms:v,maxVaryings:p,maxFragmentUniforms:r,vertexTextures:l,floatFragmentTextures:t,floatVertexTextures:l&&t}}function kd(a){qa.call(this);this.cameras=a||[]}function hg(a){var b=this,c=null,d=null;"VRFrameData"in window&&(d=new window.VRFrameData);
-var e=new K,f=new K,g=new K,h=new qa;h.bounds=new fa(0,0,.5,1);h.layers.enable(1);var k=new qa;k.bounds=new fa(.5,0,.5,1);k.layers.enable(2);var m=new kd([h,k]);m.layers.enable(1);m.layers.enable(2);var q,v;window.addEventListener("vrdisplaypresentchange",function(){if(c.isPresenting){var d=c.getEyeParameters("left"),e=d.renderWidth,d=d.renderHeight;v=a.getPixelRatio();q=a.getSize();a.setDrawingBufferSize(2*e,d,1)}else b.enabled&&a.setDrawingBufferSize(q.width,q.height,v)},!1);this.standing=this.enabled=
-!1;this.getDevice=function(){return c};this.setDevice=function(a){void 0!==a&&(c=a)};this.getCamera=function(a){if(null===c)return a;c.depthNear=a.near;c.depthFar=a.far;c.getFrameData(d);var b=d.pose;null!==b.position?a.position.fromArray(b.position):a.position.set(0,0,0);null!==b.orientation&&a.quaternion.fromArray(b.orientation);a.updateMatrixWorld();b=c.stageParameters;this.standing&&b&&(f.fromArray(b.sittingToStandingTransform),g.getInverse(f),a.matrixWorld.multiply(f),a.matrixWorldInverse.multiply(g));
-if(!1===c.isPresenting)return a;m.matrixWorld.copy(a.matrixWorld);m.matrixWorldInverse.copy(a.matrixWorldInverse);h.matrixWorldInverse.fromArray(d.leftViewMatrix);k.matrixWorldInverse.fromArray(d.rightViewMatrix);this.standing&&b&&(h.matrixWorldInverse.multiply(g),k.matrixWorldInverse.multiply(g));a=a.parent;null!==a&&(e.getInverse(a.matrixWorld),h.matrixWorldInverse.multiply(e),k.matrixWorldInverse.multiply(e));h.matrixWorld.getInverse(h.matrixWorldInverse);k.matrixWorld.getInverse(k.matrixWorldInverse);
-h.projectionMatrix.fromArray(d.leftProjectionMatrix);k.projectionMatrix.fromArray(d.rightProjectionMatrix);m.projectionMatrix.copy(h.projectionMatrix);a=c.getLayers();a.length&&(a=a[0],null!==a.leftBounds&&4===a.leftBounds.length&&h.bounds.fromArray(a.leftBounds),null!==a.rightBounds&&4===a.rightBounds.length&&k.bounds.fromArray(a.rightBounds));return m};this.getStandingMatrix=function(){return f};this.submitFrame=function(){c&&c.isPresenting&&c.submitFrame()}}function ig(a){var b={};return{get:function(c){if(void 0!==
-b[c])return b[c];var d;switch(c){case "WEBGL_depth_texture":d=a.getExtension("WEBGL_depth_texture")||a.getExtension("MOZ_WEBGL_depth_texture")||a.getExtension("WEBKIT_WEBGL_depth_texture");break;case "EXT_texture_filter_anisotropic":d=a.getExtension("EXT_texture_filter_anisotropic")||a.getExtension("MOZ_EXT_texture_filter_anisotropic")||a.getExtension("WEBKIT_EXT_texture_filter_anisotropic");break;case "WEBGL_compressed_texture_s3tc":d=a.getExtension("WEBGL_compressed_texture_s3tc")||a.getExtension("MOZ_WEBGL_compressed_texture_s3tc")||
-a.getExtension("WEBKIT_WEBGL_compressed_texture_s3tc");break;case "WEBGL_compressed_texture_pvrtc":d=a.getExtension("WEBGL_compressed_texture_pvrtc")||a.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc");break;case "WEBGL_compressed_texture_etc1":d=a.getExtension("WEBGL_compressed_texture_etc1");break;default:d=a.getExtension(c)}null===d&&console.warn("THREE.WebGLRenderer: "+c+" extension not supported.");return b[c]=d}}}function jg(){function a(){m.value!==d&&(m.value=d,m.needsUpdate=0<e);c.numPlanes=
-e;c.numIntersection=0}function b(a,b,d,e){var f=null!==a?a.length:0,g=null;if(0!==f){g=m.value;if(!0!==e||null===g){e=d+4*f;b=b.matrixWorldInverse;k.getNormalMatrix(b);if(null===g||g.length<e)g=new Float32Array(e);for(e=0;e!==f;++e,d+=4)h.copy(a[e]).applyMatrix4(b,k),h.normal.toArray(g,d),g[d+3]=h.constant}m.value=g;m.needsUpdate=!0}c.numPlanes=f;return g}var c=this,d=null,e=0,f=!1,g=!1,h=new Aa,k=new Ba,m={value:null,needsUpdate:!1};this.uniform=m;this.numIntersection=this.numPlanes=0;this.init=
-function(a,c,g){var h=0!==a.length||c||0!==e||f;f=c;d=b(a,g,0);e=a.length;return h};this.beginShadows=function(){g=!0;b(null)};this.endShadows=function(){g=!1;a()};this.setState=function(c,h,k,r,l,t){if(!f||null===c||0===c.length||g&&!k)g?b(null):a();else{k=g?0:e;var n=4*k,x=l.clippingState||null;m.value=x;x=b(c,r,n,t);for(c=0;c!==n;++c)x[c]=d[c];l.clippingState=x;this.numIntersection=h?this.numPlanes:0;this.numPlanes+=k}}}function Xd(a){function b(){ga.init();ga.scissor(J.copy(ea).multiplyScalar(Q));
-ga.viewport(U.copy(hd).multiplyScalar(Q))}function c(){S=G=null;pa="";V=-1;ga.reset()}function d(a){a.preventDefault();c();b();ha.clear();xa.clear()}function e(a){a=a.target;a.removeEventListener("dispose",e);f(a);ha.remove(a)}function f(a){var b=ha.get(a).program;a.program=void 0;void 0!==b&&va.releaseProgram(b)}function g(a,b,c){a.render(function(a){B.renderBufferImmediate(a,b,c)})}function h(a,b){return Math.abs(b[0])-Math.abs(a[0])}function k(a,b,c){if(a.visible){if(a.layers.test(b.layers))if(a.isLight)aa.push(a);
-else if(a.isSprite)a.frustumCulled&&!Vd.intersectsSprite(a)||C.push(a);else if(a.isLensFlare)z.push(a);else if(a.isImmediateRenderObject)c&&Oa.setFromMatrixPosition(a.matrixWorld).applyMatrix4(jd),F.push(a,null,a.material,Oa.z,null);else if(a.isMesh||a.isLine||a.isPoints)if(a.isSkinnedMesh&&a.skeleton.update(),!a.frustumCulled||Vd.intersectsObject(a)){c&&Oa.setFromMatrixPosition(a.matrixWorld).applyMatrix4(jd);var d=xa.update(a),e=a.material;if(Array.isArray(e))for(var f=d.groups,g=0,h=f.length;g<
-h;g++){var m=f[g],q=e[m.materialIndex];q&&q.visible&&F.push(a,d,q,Oa.z,m)}else e.visible&&F.push(a,d,e,Oa.z,null)}a=a.children;g=0;for(h=a.length;g<h;g++)k(a[g],b,c)}}function m(a,b,c,d){for(var e=0,f=a.length;e<f;e++){var g=a[e],h=g.object,k=g.geometry,m=void 0===d?g.material:d,g=g.group;if(c.isArrayCamera){N=c;for(var p=c.cameras,v=0,r=p.length;v<r;v++){var l=p[v];if(h.layers.test(l.layers)){var t=l.bounds,n=t.x*ba,ca=t.y*L,u=t.z*ba,t=t.w*L;B.setViewport(n,ca,u,t);B.setScissor(n,ca,u,t);B.setScissorTest(!0);
-q(h,b,l,k,m,g)}}}else N=null,q(h,b,c,k,m,g)}}function q(a,b,c,d,e,f){a.modelViewMatrix.multiplyMatrices(c.matrixWorldInverse,a.matrixWorld);a.normalMatrix.getNormalMatrix(a.modelViewMatrix);a.onBeforeRender(B,b,c,d,e,f);if(a.isImmediateRenderObject){ga.setMaterial(e);var h=p(c,b.fog,e,a);pa="";g(a,h,e)}else B.renderBufferDirect(c,b.fog,d,e,a,f);a.onAfterRender(B,b,c,d,e,f)}function v(a,b,c){var d=ha.get(a);c=va.getParameters(a,da,b,Ha.numPlanes,Ha.numIntersection,c);var g=va.getProgramCode(a,c),h=
-d.program,k=!0;if(void 0===h)a.addEventListener("dispose",e);else if(h.code!==g)f(a);else{if(void 0!==c.shaderID)return;k=!1}k&&(c.shaderID?(h=$a[c.shaderID],d.shader={name:a.type,uniforms:Ca.clone(h.uniforms),vertexShader:h.vertexShader,fragmentShader:h.fragmentShader}):d.shader={name:a.type,uniforms:a.uniforms,vertexShader:a.vertexShader,fragmentShader:a.fragmentShader},a.onBeforeCompile(d.shader),h=va.acquireProgram(a,d.shader,c,g),d.program=h,a.program=h);c=h.getAttributes();if(a.morphTargets)for(g=
-a.numSupportedMorphTargets=0;g<B.maxMorphTargets;g++)0<=c["morphTarget"+g]&&a.numSupportedMorphTargets++;if(a.morphNormals)for(g=a.numSupportedMorphNormals=0;g<B.maxMorphNormals;g++)0<=c["morphNormal"+g]&&a.numSupportedMorphNormals++;c=d.shader.uniforms;if(!a.isShaderMaterial&&!a.isRawShaderMaterial||!0===a.clipping)d.numClippingPlanes=Ha.numPlanes,d.numIntersection=Ha.numIntersection,c.clippingPlanes=Ha.uniform;d.fog=b;d.lightsHash=da.hash;a.lights&&(c.ambientLightColor.value=da.ambient,c.directionalLights.value=
-da.directional,c.spotLights.value=da.spot,c.rectAreaLights.value=da.rectArea,c.pointLights.value=da.point,c.hemisphereLights.value=da.hemi,c.directionalShadowMap.value=da.directionalShadowMap,c.directionalShadowMatrix.value=da.directionalShadowMatrix,c.spotShadowMap.value=da.spotShadowMap,c.spotShadowMatrix.value=da.spotShadowMatrix,c.pointShadowMap.value=da.pointShadowMap,c.pointShadowMatrix.value=da.pointShadowMatrix);a=d.program.getUniforms();a=eb.seqWithValue(a.seq,c);d.uniformsList=a}function p(a,
-b,c,d){X=0;var e=ha.get(c);id&&(Wd||a!==S)&&Ha.setState(c.clippingPlanes,c.clipIntersection,c.clipShadows,a,e,a===S&&c.id===V);!1===c.needsUpdate&&(void 0===e.program?c.needsUpdate=!0:c.fog&&e.fog!==b?c.needsUpdate=!0:c.lights&&e.lightsHash!==da.hash?c.needsUpdate=!0:void 0===e.numClippingPlanes||e.numClippingPlanes===Ha.numPlanes&&e.numIntersection===Ha.numIntersection||(c.needsUpdate=!0));c.needsUpdate&&(v(c,b,d),c.needsUpdate=!1);var f=!1,g=!1,h=!1,k=e.program,m=k.getUniforms(),q=e.shader.uniforms;
-k.id!==G&&(A.useProgram(k.program),G=k.id,h=g=f=!0);c.id!==V&&(V=c.id,g=!0);if(f||a!==S){m.setValue(A,"projectionMatrix",a.projectionMatrix);ia.logarithmicDepthBuffer&&m.setValue(A,"logDepthBufFC",2/(Math.log(a.far+1)/Math.LN2));S!==(N||a)&&(S=N||a,h=g=!0);if(c.isShaderMaterial||c.isMeshPhongMaterial||c.isMeshStandardMaterial||c.envMap)f=m.map.cameraPosition,void 0!==f&&f.setValue(A,Oa.setFromMatrixPosition(a.matrixWorld));(c.isMeshPhongMaterial||c.isMeshLambertMaterial||c.isMeshBasicMaterial||c.isMeshStandardMaterial||
-c.isShaderMaterial||c.skinning)&&m.setValue(A,"viewMatrix",a.matrixWorldInverse)}if(c.skinning&&(m.setOptional(A,d,"bindMatrix"),m.setOptional(A,d,"bindMatrixInverse"),a=d.skeleton))if(f=a.bones,ia.floatVertexTextures){if(void 0===a.boneTexture){var f=Math.sqrt(4*f.length),f=Y.nextPowerOfTwo(Math.ceil(f)),f=Math.max(f,4),p=new Float32Array(f*f*4);p.set(a.boneMatrices);var t=new db(p,f,f,1023,1015);a.boneMatrices=p;a.boneTexture=t;a.boneTextureSize=f}m.setValue(A,"boneTexture",a.boneTexture);m.setValue(A,
-"boneTextureSize",a.boneTextureSize)}else m.setOptional(A,a,"boneMatrices");if(g){m.setValue(A,"toneMappingExposure",B.toneMappingExposure);m.setValue(A,"toneMappingWhitePoint",B.toneMappingWhitePoint);c.lights&&(g=h,q.ambientLightColor.needsUpdate=g,q.directionalLights.needsUpdate=g,q.pointLights.needsUpdate=g,q.spotLights.needsUpdate=g,q.rectAreaLights.needsUpdate=g,q.hemisphereLights.needsUpdate=g);b&&c.fog&&(q.fogColor.value=b.color,b.isFog?(q.fogNear.value=b.near,q.fogFar.value=b.far):b.isFogExp2&&
-(q.fogDensity.value=b.density));if(c.isMeshBasicMaterial||c.isMeshLambertMaterial||c.isMeshPhongMaterial||c.isMeshStandardMaterial||c.isMeshNormalMaterial||c.isMeshDepthMaterial){q.opacity.value=c.opacity;q.diffuse.value=c.color;c.emissive&&q.emissive.value.copy(c.emissive).multiplyScalar(c.emissiveIntensity);q.map.value=c.map;q.specularMap.value=c.specularMap;q.alphaMap.value=c.alphaMap;c.lightMap&&(q.lightMap.value=c.lightMap,q.lightMapIntensity.value=c.lightMapIntensity);c.aoMap&&(q.aoMap.value=
-c.aoMap,q.aoMapIntensity.value=c.aoMapIntensity);var n;c.map?n=c.map:c.specularMap?n=c.specularMap:c.displacementMap?n=c.displacementMap:c.normalMap?n=c.normalMap:c.bumpMap?n=c.bumpMap:c.roughnessMap?n=c.roughnessMap:c.metalnessMap?n=c.metalnessMap:c.alphaMap?n=c.alphaMap:c.emissiveMap&&(n=c.emissiveMap);void 0!==n&&(n.isWebGLRenderTarget&&(n=n.texture),b=n.offset,n=n.repeat,q.offsetRepeat.value.set(b.x,b.y,n.x,n.y));q.envMap.value=c.envMap;q.flipEnvMap.value=c.envMap&&c.envMap.isCubeTexture?-1:1;
-q.reflectivity.value=c.reflectivity;q.refractionRatio.value=c.refractionRatio}c.isLineBasicMaterial?(q.diffuse.value=c.color,q.opacity.value=c.opacity):c.isLineDashedMaterial?(q.diffuse.value=c.color,q.opacity.value=c.opacity,q.dashSize.value=c.dashSize,q.totalSize.value=c.dashSize+c.gapSize,q.scale.value=c.scale):c.isPointsMaterial?(q.diffuse.value=c.color,q.opacity.value=c.opacity,q.size.value=c.size*Q,q.scale.value=.5*L,q.map.value=c.map,null!==c.map&&(n=c.map.offset,c=c.map.repeat,q.offsetRepeat.value.set(n.x,
-n.y,c.x,c.y))):c.isMeshLambertMaterial?c.emissiveMap&&(q.emissiveMap.value=c.emissiveMap):c.isMeshToonMaterial?(r(q,c),c.gradientMap&&(q.gradientMap.value=c.gradientMap)):c.isMeshPhongMaterial?r(q,c):c.isMeshPhysicalMaterial?(q.clearCoat.value=c.clearCoat,q.clearCoatRoughness.value=c.clearCoatRoughness,l(q,c)):c.isMeshStandardMaterial?l(q,c):c.isMeshDepthMaterial?c.displacementMap&&(q.displacementMap.value=c.displacementMap,q.displacementScale.value=c.displacementScale,q.displacementBias.value=c.displacementBias):
-c.isMeshNormalMaterial&&(c.bumpMap&&(q.bumpMap.value=c.bumpMap,q.bumpScale.value=c.bumpScale),c.normalMap&&(q.normalMap.value=c.normalMap,q.normalScale.value.copy(c.normalScale)),c.displacementMap&&(q.displacementMap.value=c.displacementMap,q.displacementScale.value=c.displacementScale,q.displacementBias.value=c.displacementBias));void 0!==q.ltcMat&&(q.ltcMat.value=R.LTC_MAT_TEXTURE);void 0!==q.ltcMag&&(q.ltcMag.value=R.LTC_MAG_TEXTURE);eb.upload(A,e.uniformsList,q,B)}m.setValue(A,"modelViewMatrix",
-d.modelViewMatrix);m.setValue(A,"normalMatrix",d.normalMatrix);m.setValue(A,"modelMatrix",d.matrixWorld);return k}function r(a,b){a.specular.value=b.specular;a.shininess.value=Math.max(b.shininess,1E-4);b.emissiveMap&&(a.emissiveMap.value=b.emissiveMap);b.bumpMap&&(a.bumpMap.value=b.bumpMap,a.bumpScale.value=b.bumpScale);b.normalMap&&(a.normalMap.value=b.normalMap,a.normalScale.value.copy(b.normalScale));b.displacementMap&&(a.displacementMap.value=b.displacementMap,a.displacementScale.value=b.displacementScale,
-a.displacementBias.value=b.displacementBias)}function l(a,b){a.roughness.value=b.roughness;a.metalness.value=b.metalness;b.roughnessMap&&(a.roughnessMap.value=b.roughnessMap);b.metalnessMap&&(a.metalnessMap.value=b.metalnessMap);b.emissiveMap&&(a.emissiveMap.value=b.emissiveMap);b.bumpMap&&(a.bumpMap.value=b.bumpMap,a.bumpScale.value=b.bumpScale);b.normalMap&&(a.normalMap.value=b.normalMap,a.normalScale.value.copy(b.normalScale));b.displacementMap&&(a.displacementMap.value=b.displacementMap,a.displacementScale.value=
-b.displacementScale,a.displacementBias.value=b.displacementBias);b.envMap&&(a.envMapIntensity.value=b.envMapIntensity)}function t(a,b){var c,d,e,f,g=0,h=0,k=0,m,q,p,v=b.matrixWorldInverse,r=0,l=0,n=0,t=0,ca=0;c=0;for(d=a.length;c<d;c++)if(e=a[c],f=e.color,m=e.intensity,q=e.distance,p=e.shadow&&e.shadow.map?e.shadow.map.texture:null,e.isAmbientLight)g+=f.r*m,h+=f.g*m,k+=f.b*m;else if(e.isDirectionalLight){var u=wa.get(e);u.color.copy(e.color).multiplyScalar(e.intensity);u.direction.setFromMatrixPosition(e.matrixWorld);
-Oa.setFromMatrixPosition(e.target.matrixWorld);u.direction.sub(Oa);u.direction.transformDirection(v);if(u.shadow=e.castShadow)f=e.shadow,u.shadowBias=f.bias,u.shadowRadius=f.radius,u.shadowMapSize=f.mapSize;da.directionalShadowMap[r]=p;da.directionalShadowMatrix[r]=e.shadow.matrix;da.directional[r]=u;r++}else if(e.isSpotLight){u=wa.get(e);u.position.setFromMatrixPosition(e.matrixWorld);u.position.applyMatrix4(v);u.color.copy(f).multiplyScalar(m);u.distance=q;u.direction.setFromMatrixPosition(e.matrixWorld);
-Oa.setFromMatrixPosition(e.target.matrixWorld);u.direction.sub(Oa);u.direction.transformDirection(v);u.coneCos=Math.cos(e.angle);u.penumbraCos=Math.cos(e.angle*(1-e.penumbra));u.decay=0===e.distance?0:e.decay;if(u.shadow=e.castShadow)f=e.shadow,u.shadowBias=f.bias,u.shadowRadius=f.radius,u.shadowMapSize=f.mapSize;da.spotShadowMap[n]=p;da.spotShadowMatrix[n]=e.shadow.matrix;da.spot[n]=u;n++}else if(e.isRectAreaLight)u=wa.get(e),u.color.copy(f).multiplyScalar(m/(e.width*e.height)),u.position.setFromMatrixPosition(e.matrixWorld),
-u.position.applyMatrix4(v),oa.identity(),qa.copy(e.matrixWorld),qa.premultiply(v),oa.extractRotation(qa),u.halfWidth.set(.5*e.width,0,0),u.halfHeight.set(0,.5*e.height,0),u.halfWidth.applyMatrix4(oa),u.halfHeight.applyMatrix4(oa),da.rectArea[t]=u,t++;else if(e.isPointLight){u=wa.get(e);u.position.setFromMatrixPosition(e.matrixWorld);u.position.applyMatrix4(v);u.color.copy(e.color).multiplyScalar(e.intensity);u.distance=e.distance;u.decay=0===e.distance?0:e.decay;if(u.shadow=e.castShadow)f=e.shadow,
-u.shadowBias=f.bias,u.shadowRadius=f.radius,u.shadowMapSize=f.mapSize;da.pointShadowMap[l]=p;da.pointShadowMatrix[l]=e.shadow.matrix;da.point[l]=u;l++}else e.isHemisphereLight&&(u=wa.get(e),u.direction.setFromMatrixPosition(e.matrixWorld),u.direction.transformDirection(v),u.direction.normalize(),u.skyColor.copy(e.color).multiplyScalar(m),u.groundColor.copy(e.groundColor).multiplyScalar(m),da.hemi[ca]=u,ca++);da.ambient[0]=g;da.ambient[1]=h;da.ambient[2]=k;da.directional.length=r;da.spot.length=n;
-da.rectArea.length=t;da.point.length=l;da.hemi.length=ca;da.hash=r+","+l+","+n+","+t+","+ca+","+da.shadows.length}function y(a){var b;if(1E3===a)return A.REPEAT;if(1001===a)return A.CLAMP_TO_EDGE;if(1002===a)return A.MIRRORED_REPEAT;if(1003===a)return A.NEAREST;if(1004===a)return A.NEAREST_MIPMAP_NEAREST;if(1005===a)return A.NEAREST_MIPMAP_LINEAR;if(1006===a)return A.LINEAR;if(1007===a)return A.LINEAR_MIPMAP_NEAREST;if(1008===a)return A.LINEAR_MIPMAP_LINEAR;if(1009===a)return A.UNSIGNED_BYTE;if(1017===
-a)return A.UNSIGNED_SHORT_4_4_4_4;if(1018===a)return A.UNSIGNED_SHORT_5_5_5_1;if(1019===a)return A.UNSIGNED_SHORT_5_6_5;if(1010===a)return A.BYTE;if(1011===a)return A.SHORT;if(1012===a)return A.UNSIGNED_SHORT;if(1013===a)return A.INT;if(1014===a)return A.UNSIGNED_INT;if(1015===a)return A.FLOAT;if(1016===a&&(b=ma.get("OES_texture_half_float"),null!==b))return b.HALF_FLOAT_OES;if(1021===a)return A.ALPHA;if(1022===a)return A.RGB;if(1023===a)return A.RGBA;if(1024===a)return A.LUMINANCE;if(1025===a)return A.LUMINANCE_ALPHA;
-if(1026===a)return A.DEPTH_COMPONENT;if(1027===a)return A.DEPTH_STENCIL;if(100===a)return A.FUNC_ADD;if(101===a)return A.FUNC_SUBTRACT;if(102===a)return A.FUNC_REVERSE_SUBTRACT;if(200===a)return A.ZERO;if(201===a)return A.ONE;if(202===a)return A.SRC_COLOR;if(203===a)return A.ONE_MINUS_SRC_COLOR;if(204===a)return A.SRC_ALPHA;if(205===a)return A.ONE_MINUS_SRC_ALPHA;if(206===a)return A.DST_ALPHA;if(207===a)return A.ONE_MINUS_DST_ALPHA;if(208===a)return A.DST_COLOR;if(209===a)return A.ONE_MINUS_DST_COLOR;
-if(210===a)return A.SRC_ALPHA_SATURATE;if(2001===a||2002===a||2003===a||2004===a)if(b=ma.get("WEBGL_compressed_texture_s3tc"),null!==b){if(2001===a)return b.COMPRESSED_RGB_S3TC_DXT1_EXT;if(2002===a)return b.COMPRESSED_RGBA_S3TC_DXT1_EXT;if(2003===a)return b.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(2004===a)return b.COMPRESSED_RGBA_S3TC_DXT5_EXT}if(2100===a||2101===a||2102===a||2103===a)if(b=ma.get("WEBGL_compressed_texture_pvrtc"),null!==b){if(2100===a)return b.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(2101===a)return b.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
-if(2102===a)return b.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(2103===a)return b.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}if(2151===a&&(b=ma.get("WEBGL_compressed_texture_etc1"),null!==b))return b.COMPRESSED_RGB_ETC1_WEBGL;if(103===a||104===a)if(b=ma.get("EXT_blend_minmax"),null!==b){if(103===a)return b.MIN_EXT;if(104===a)return b.MAX_EXT}return 1020===a&&(b=ma.get("WEBGL_depth_texture"),null!==b)?b.UNSIGNED_INT_24_8_WEBGL:0}console.log("THREE.WebGLRenderer","86");a=a||{};var x=void 0!==a.canvas?a.canvas:document.createElementNS("http://www.w3.org/1999/xhtml",
-"canvas"),u=void 0!==a.context?a.context:null,H=void 0!==a.alpha?a.alpha:!1,w=void 0!==a.depth?a.depth:!0,I=void 0!==a.stencil?a.stencil:!0,W=void 0!==a.antialias?a.antialias:!1,D=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,O=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,aa=[],F=null,ja=new Float32Array(8),C=[],z=[];this.domElement=x;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;this.clippingPlanes=[];this.localClippingEnabled=
-!1;this.gammaFactor=2;this.physicallyCorrectLights=this.gammaOutput=this.gammaInput=!1;this.toneMappingWhitePoint=this.toneMappingExposure=this.toneMapping=1;this.maxMorphTargets=8;this.maxMorphNormals=4;var B=this,G=null,P=null,M=null,V=-1,pa="",S=null,N=null,J=new fa,Z=null,U=new fa,X=0,ba=x.width,L=x.height,Q=1,ea=new fa(0,0,ba,L),na=!1,hd=new fa(0,0,ba,L),Vd=new gd,Ha=new jg,id=!1,Wd=!1,jd=new K,Oa=new n,qa=new K,oa=new K,da={hash:"",ambient:[0,0,0],directional:[],directionalShadowMap:[],directionalShadowMatrix:[],
-spot:[],spotShadowMap:[],spotShadowMatrix:[],rectArea:[],point:[],pointShadowMap:[],pointShadowMatrix:[],hemi:[],shadows:[]},ta={geometries:0,textures:0},la={frame:0,calls:0,vertices:0,faces:0,points:0};this.info={render:la,memory:ta,programs:null};var A;try{H={alpha:H,depth:w,stencil:I,antialias:W,premultipliedAlpha:D,preserveDrawingBuffer:O};A=u||x.getContext("webgl",H)||x.getContext("experimental-webgl",H);if(null===A){if(null!==x.getContext("webgl"))throw"Error creating WebGL context with your selected attributes.";
-throw"Error creating WebGL context.";}void 0===A.getShaderPrecisionFormat&&(A.getShaderPrecisionFormat=function(){return{rangeMin:1,rangeMax:1,precision:1}});x.addEventListener("webglcontextlost",d,!1)}catch(kg){console.error("THREE.WebGLRenderer: "+kg)}var ma=new ig(A);ma.get("WEBGL_depth_texture");ma.get("OES_texture_float");ma.get("OES_texture_float_linear");ma.get("OES_texture_half_float");ma.get("OES_texture_half_float_linear");ma.get("OES_standard_derivatives");ma.get("ANGLE_instanced_arrays");
-ma.get("OES_element_index_uint")&&(E.MaxIndex=4294967296);var ia=new gg(A,ma,a),ga=new fg(A,ma,y),ha=new eg,ra=new dg(A,ma,ga,ha,ia,y,ta),ua=new Kf(A),za=new Tf(A,ua,ta),xa=new Vf(A,za,la),va=new cg(this,ia),wa=new Uf,Aa=new Qf,ya=new Mf(this,ga,xa,D),sa=new hg(this);this.info.programs=va.programs;var Da=new Sf(A,ma,la),Ea=new Rf(A,ma,la);b();this.context=A;this.capabilities=ia;this.extensions=ma;this.properties=ha;this.renderLists=Aa;this.state=ga;this.vr=sa;var Ba=new Ie(this,da,xa,ia);this.shadowMap=
-Ba;var Fa=new If(this,C),Ga=new Hf(this,z);this.getContext=function(){return A};this.getContextAttributes=function(){return A.getContextAttributes()};this.forceContextLoss=function(){var a=ma.get("WEBGL_lose_context");a&&a.loseContext()};this.getMaxAnisotropy=function(){return ia.getMaxAnisotropy()};this.getPrecision=function(){return ia.precision};this.getPixelRatio=function(){return Q};this.setPixelRatio=function(a){void 0!==a&&(Q=a,this.setSize(ba,L,!1))};this.getSize=function(){return{width:ba,
-height:L}};this.setSize=function(a,b,c){var d=sa.getDevice();d&&d.isPresenting?console.warn("THREE.WebGLRenderer: Can't change size while VR device is presenting."):(ba=a,L=b,x.width=a*Q,x.height=b*Q,!1!==c&&(x.style.width=a+"px",x.style.height=b+"px"),this.setViewport(0,0,a,b))};this.getDrawingBufferSize=function(){return{width:ba*Q,height:L*Q}};this.setDrawingBufferSize=function(a,b,c){ba=a;L=b;Q=c;x.width=a*c;x.height=b*c;this.setViewport(0,0,a,b)};this.setViewport=function(a,b,c,d){hd.set(a,L-
-b-d,c,d);ga.viewport(U.copy(hd).multiplyScalar(Q))};this.setScissor=function(a,b,c,d){ea.set(a,L-b-d,c,d);ga.scissor(J.copy(ea).multiplyScalar(Q))};this.setScissorTest=function(a){ga.setScissorTest(na=a)};this.getClearColor=ya.getClearColor;this.setClearColor=ya.setClearColor;this.getClearAlpha=ya.getClearAlpha;this.setClearAlpha=ya.setClearAlpha;this.clear=function(a,b,c){var d=0;if(void 0===a||a)d|=A.COLOR_BUFFER_BIT;if(void 0===b||b)d|=A.DEPTH_BUFFER_BIT;if(void 0===c||c)d|=A.STENCIL_BUFFER_BIT;
-A.clear(d)};this.clearColor=function(){this.clear(!0,!1,!1)};this.clearDepth=function(){this.clear(!1,!0,!1)};this.clearStencil=function(){this.clear(!1,!1,!0)};this.clearTarget=function(a,b,c,d){this.setRenderTarget(a);this.clear(b,c,d)};this.resetGLState=c;this.dispose=function(){x.removeEventListener("webglcontextlost",d,!1);Aa.dispose()};this.renderBufferImmediate=function(a,b,c){ga.initAttributes();var d=ha.get(a);a.hasPositions&&!d.position&&(d.position=A.createBuffer());a.hasNormals&&!d.normal&&
-(d.normal=A.createBuffer());a.hasUvs&&!d.uv&&(d.uv=A.createBuffer());a.hasColors&&!d.color&&(d.color=A.createBuffer());b=b.getAttributes();a.hasPositions&&(A.bindBuffer(A.ARRAY_BUFFER,d.position),A.bufferData(A.ARRAY_BUFFER,a.positionArray,A.DYNAMIC_DRAW),ga.enableAttribute(b.position),A.vertexAttribPointer(b.position,3,A.FLOAT,!1,0,0));if(a.hasNormals){A.bindBuffer(A.ARRAY_BUFFER,d.normal);if(!c.isMeshPhongMaterial&&!c.isMeshStandardMaterial&&!c.isMeshNormalMaterial&&1===c.shading)for(var e=0,f=
-3*a.count;e<f;e+=9){var g=a.normalArray,h=(g[e+0]+g[e+3]+g[e+6])/3,k=(g[e+1]+g[e+4]+g[e+7])/3,m=(g[e+2]+g[e+5]+g[e+8])/3;g[e+0]=h;g[e+1]=k;g[e+2]=m;g[e+3]=h;g[e+4]=k;g[e+5]=m;g[e+6]=h;g[e+7]=k;g[e+8]=m}A.bufferData(A.ARRAY_BUFFER,a.normalArray,A.DYNAMIC_DRAW);ga.enableAttribute(b.normal);A.vertexAttribPointer(b.normal,3,A.FLOAT,!1,0,0)}a.hasUvs&&c.map&&(A.bindBuffer(A.ARRAY_BUFFER,d.uv),A.bufferData(A.ARRAY_BUFFER,a.uvArray,A.DYNAMIC_DRAW),ga.enableAttribute(b.uv),A.vertexAttribPointer(ua.uv,2,A.FLOAT,
-!1,0,0));a.hasColors&&0!==c.vertexColors&&(A.bindBuffer(A.ARRAY_BUFFER,d.color),A.bufferData(A.ARRAY_BUFFER,a.colorArray,A.DYNAMIC_DRAW),ga.enableAttribute(b.color),A.vertexAttribPointer(b.color,3,A.FLOAT,!1,0,0));ga.disableUnusedAttributes();A.drawArrays(A.TRIANGLES,0,a.count);a.count=0};this.renderBufferDirect=function(a,b,c,d,e,f){ga.setMaterial(d);var g=p(a,b,d,e);a=c.id+"_"+g.id+"_"+(!0===d.wireframe);var k=!1;a!==pa&&(pa=a,k=!0);b=e.morphTargetInfluences;if(void 0!==b){var m=[];a=0;for(var q=
-b.length;a<q;a++)k=b[a],m.push([k,a]);m.sort(h);8<m.length&&(m.length=8);var v=c.morphAttributes;a=0;for(q=m.length;a<q;a++)k=m[a],ja[a]=k[0],0!==k[0]?(b=k[1],!0===d.morphTargets&&v.position&&c.addAttribute("morphTarget"+a,v.position[b]),!0===d.morphNormals&&v.normal&&c.addAttribute("morphNormal"+a,v.normal[b])):(!0===d.morphTargets&&c.removeAttribute("morphTarget"+a),!0===d.morphNormals&&c.removeAttribute("morphNormal"+a));a=m.length;for(b=ja.length;a<b;a++)ja[a]=0;g.getUniforms().setValue(A,"morphTargetInfluences",
-ja);k=!0}b=c.index;q=c.attributes.position;m=1;!0===d.wireframe&&(b=za.getWireframeAttribute(c),m=2);var r;a=Da;null!==b&&(r=ua.get(b),a=Ea,a.setIndex(r));if(k){k=void 0;if(c&&c.isInstancedBufferGeometry&&null===ma.get("ANGLE_instanced_arrays"))console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.");else{void 0===k&&(k=0);ga.initAttributes();var v=c.attributes,g=g.getAttributes(),l=d.defaultAttributeValues,
-n;for(n in g){var t=g[n];if(0<=t){var u=v[n];if(void 0!==u){var ca=u.normalized,w=u.itemSize,x=ua.get(u),y=x.buffer,H=x.type,x=x.bytesPerElement;if(u.isInterleavedBufferAttribute){var I=u.data,D=I.stride,u=u.offset;I&&I.isInstancedInterleavedBuffer?(ga.enableAttributeAndDivisor(t,I.meshPerAttribute),void 0===c.maxInstancedCount&&(c.maxInstancedCount=I.meshPerAttribute*I.count)):ga.enableAttribute(t);A.bindBuffer(A.ARRAY_BUFFER,y);A.vertexAttribPointer(t,w,H,ca,D*x,(k*D+u)*x)}else u.isInstancedBufferAttribute?
-(ga.enableAttributeAndDivisor(t,u.meshPerAttribute),void 0===c.maxInstancedCount&&(c.maxInstancedCount=u.meshPerAttribute*u.count)):ga.enableAttribute(t),A.bindBuffer(A.ARRAY_BUFFER,y),A.vertexAttribPointer(t,w,H,ca,0,k*w*x)}else if(void 0!==l&&(ca=l[n],void 0!==ca))switch(ca.length){case 2:A.vertexAttrib2fv(t,ca);break;case 3:A.vertexAttrib3fv(t,ca);break;case 4:A.vertexAttrib4fv(t,ca);break;default:A.vertexAttrib1fv(t,ca)}}}ga.disableUnusedAttributes()}null!==b&&A.bindBuffer(A.ELEMENT_ARRAY_BUFFER,
-r.buffer)}r=0;null!==b?r=b.count:void 0!==q&&(r=q.count);b=c.drawRange.start*m;q=null!==f?f.start*m:0;n=Math.max(b,q);f=Math.max(0,Math.min(r,b+c.drawRange.count*m,q+(null!==f?f.count*m:Infinity))-1-n+1);if(0!==f){if(e.isMesh)if(!0===d.wireframe)ga.setLineWidth(d.wireframeLinewidth*(null===P?Q:1)),a.setMode(A.LINES);else switch(e.drawMode){case 0:a.setMode(A.TRIANGLES);break;case 1:a.setMode(A.TRIANGLE_STRIP);break;case 2:a.setMode(A.TRIANGLE_FAN)}else e.isLine?(d=d.linewidth,void 0===d&&(d=1),ga.setLineWidth(d*
-(null===P?Q:1)),e.isLineSegments?a.setMode(A.LINES):e.isLineLoop?a.setMode(A.LINE_LOOP):a.setMode(A.LINE_STRIP)):e.isPoints&&a.setMode(A.POINTS);c&&c.isInstancedBufferGeometry?0<c.maxInstancedCount&&a.renderInstances(c,n,f):a.render(n,f)}};this.compile=function(a,b){aa=[];a.traverse(function(a){a.isLight&&aa.push(a)});t(aa,b);a.traverse(function(b){if(b.material)if(Array.isArray(b.material))for(var c=0;c<b.material.length;c++)v(b.material[c],a.fog,b);else v(b.material,a.fog,b)})};this.animate=function(a){function b(){a();
-(sa.getDevice()||window).requestAnimationFrame(b)}(sa.getDevice()||window).requestAnimationFrame(b)};this.render=function(a,b,c,d){if(b&&b.isCamera){pa="";V=-1;S=null;!0===a.autoUpdate&&a.updateMatrixWorld();null===b.parent&&b.updateMatrixWorld();sa.enabled&&(b=sa.getCamera(b));jd.multiplyMatrices(b.projectionMatrix,b.matrixWorldInverse);Vd.setFromMatrix(jd);aa.length=0;C.length=0;z.length=0;Wd=this.localClippingEnabled;id=Ha.init(this.clippingPlanes,Wd,b);F=Aa.get(a,b);F.init();k(a,b,B.sortObjects);
-F.finish();!0===B.sortObjects&&F.sort();id&&Ha.beginShadows();for(var e=aa,f=0,g=0,h=e.length;g<h;g++){var q=e[g];q.castShadow&&(da.shadows[f]=q,f++)}da.shadows.length=f;Ba.render(a,b);t(aa,b);id&&Ha.endShadows();la.frame++;la.calls=0;la.vertices=0;la.faces=0;la.points=0;void 0===c&&(c=null);this.setRenderTarget(c);ya.render(a,b,d);d=F.opaque;e=F.transparent;a.overrideMaterial?(f=a.overrideMaterial,d.length&&m(d,a,b,f),e.length&&m(e,a,b,f)):(d.length&&m(d,a,b),e.length&&m(e,a,b));Fa.render(a,b);Ga.render(a,
-b,U);c&&ra.updateRenderTargetMipmap(c);ga.buffers.depth.setTest(!0);ga.buffers.depth.setMask(!0);ga.buffers.color.setMask(!0);b.isArrayCamera&&B.setScissorTest(!1);sa.enabled&&sa.submitFrame()}else console.error("THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.")};this.setFaceCulling=function(a,b){ga.setCullFace(a);ga.setFlipSided(0===b)};this.allocTextureUnit=function(){var a=X;a>=ia.maxTextures&&console.warn("THREE.WebGLRenderer: Trying to use "+a+" texture units while this GPU supports only "+
-ia.maxTextures);X+=1;return a};this.setTexture2D=function(){var a=!1;return function(b,c){b&&b.isWebGLRenderTarget&&(a||(console.warn("THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead."),a=!0),b=b.texture);ra.setTexture2D(b,c)}}();this.setTexture=function(){var a=!1;return function(b,c){a||(console.warn("THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead."),a=!0);ra.setTexture2D(b,c)}}();this.setTextureCube=function(){var a=
-!1;return function(b,c){b&&b.isWebGLRenderTargetCube&&(a||(console.warn("THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead."),a=!0),b=b.texture);b&&b.isCubeTexture||Array.isArray(b.image)&&6===b.image.length?ra.setTextureCube(b,c):ra.setTextureCubeDynamic(b,c)}}();this.getRenderTarget=function(){return P};this.setRenderTarget=function(a){(P=a)&&void 0===ha.get(a).__webglFramebuffer&&ra.setupRenderTarget(a);var b=a&&a.isWebGLRenderTargetCube,
-c;a?(c=ha.get(a),c=b?c.__webglFramebuffer[a.activeCubeFace]:c.__webglFramebuffer,J.copy(a.scissor),Z=a.scissorTest,U.copy(a.viewport)):(c=null,J.copy(ea).multiplyScalar(Q),Z=na,U.copy(hd).multiplyScalar(Q));M!==c&&(A.bindFramebuffer(A.FRAMEBUFFER,c),M=c);ga.scissor(J);ga.setScissorTest(Z);ga.viewport(U);b&&(b=ha.get(a.texture),A.framebufferTexture2D(A.FRAMEBUFFER,A.COLOR_ATTACHMENT0,A.TEXTURE_CUBE_MAP_POSITIVE_X+a.activeCubeFace,b.__webglTexture,a.activeMipMapLevel))};this.readRenderTargetPixels=
-function(a,b,c,d,e,f){if(a&&a.isWebGLRenderTarget){var g=ha.get(a).__webglFramebuffer;if(g){var h=!1;g!==M&&(A.bindFramebuffer(A.FRAMEBUFFER,g),h=!0);try{var k=a.texture,m=k.format,q=k.type;1023!==m&&y(m)!==A.getParameter(A.IMPLEMENTATION_COLOR_READ_FORMAT)?console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format."):1009===q||y(q)===A.getParameter(A.IMPLEMENTATION_COLOR_READ_TYPE)||1015===q&&(ma.get("OES_texture_float")||ma.get("WEBGL_color_buffer_float"))||
-1016===q&&ma.get("EXT_color_buffer_half_float")?A.checkFramebufferStatus(A.FRAMEBUFFER)===A.FRAMEBUFFER_COMPLETE?0<=b&&b<=a.width-d&&0<=c&&c<=a.height-e&&A.readPixels(b,c,d,e,y(m),y(q),f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete."):console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.")}finally{h&&A.bindFramebuffer(A.FRAMEBUFFER,M)}}}else console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.")}}
-function Ib(a,b){this.name="";this.color=new G(a);this.density=void 0!==b?b:2.5E-4}function Jb(a,b,c){this.name="";this.color=new G(a);this.near=void 0!==b?b:1;this.far=void 0!==c?c:1E3}function ld(){z.call(this);this.type="Scene";this.overrideMaterial=this.fog=this.background=null;this.autoUpdate=!0}function Yd(a,b,c,d,e){z.call(this);this.lensFlares=[];this.positionScreen=new n;this.customUpdateCallback=void 0;void 0!==a&&this.add(a,b,c,d,e)}function bb(a){U.call(this);this.type="SpriteMaterial";
-this.color=new G(16777215);this.map=null;this.rotation=0;this.lights=this.fog=!1;this.setValues(a)}function xc(a){z.call(this);this.type="Sprite";this.material=void 0!==a?a:new bb}function yc(){z.call(this);this.type="LOD";Object.defineProperties(this,{levels:{enumerable:!0,value:[]}})}function zc(a,b){a=a||[];this.bones=a.slice(0);this.boneMatrices=new Float32Array(16*this.bones.length);if(void 0===b)this.calculateInverses();else if(this.bones.length===b.length)this.boneInverses=b.slice(0);else{console.warn("THREE.Skeleton boneInverses is the wrong length.");
-this.boneInverses=[];for(var c=0,d=this.bones.length;c<d;c++)this.boneInverses.push(new K)}}function md(){z.call(this);this.type="Bone"}function nd(a,b){la.call(this,a,b);this.type="SkinnedMesh";this.bindMode="attached";this.bindMatrix=new K;this.bindMatrixInverse=new K;var c=this.initBones(),c=new zc(c);this.bind(c,this.matrixWorld);this.normalizeSkinWeights()}function ea(a){U.call(this);this.type="LineBasicMaterial";this.color=new G(16777215);this.linewidth=1;this.linejoin=this.linecap="round";
-this.lights=!1;this.setValues(a)}function sa(a,b,c){if(1===c)return console.warn("THREE.Line: parameter THREE.LinePieces no longer supported. Created THREE.LineSegments instead."),new Q(a,b);z.call(this);this.type="Line";this.geometry=void 0!==a?a:new E;this.material=void 0!==b?b:new ea({color:16777215*Math.random()})}function Q(a,b){sa.call(this,a,b);this.type="LineSegments"}function od(a,b){sa.call(this,a,b);this.type="LineLoop"}function Fa(a){U.call(this);this.type="PointsMaterial";this.color=
-new G(16777215);this.map=null;this.size=1;this.sizeAttenuation=!0;this.lights=!1;this.setValues(a)}function Kb(a,b){z.call(this);this.type="Points";this.geometry=void 0!==a?a:new E;this.material=void 0!==b?b:new Fa({color:16777215*Math.random()})}function Ac(){z.call(this);this.type="Group"}function pd(a,b,c,d,e,f,g,h,k){function m(){requestAnimationFrame(m);a.readyState>=a.HAVE_CURRENT_DATA&&(q.needsUpdate=!0)}ba.call(this,a,b,c,d,e,f,g,h,k);this.generateMipmaps=!1;var q=this;m()}function Lb(a,b,
-c,d,e,f,g,h,k,m,q,v){ba.call(this,null,f,g,h,k,m,d,e,q,v);this.image={width:b,height:c};this.mipmaps=a;this.generateMipmaps=this.flipY=!1}function qd(a,b,c,d,e,f,g,h,k){ba.call(this,a,b,c,d,e,f,g,h,k);this.needsUpdate=!0}function Bc(a,b,c,d,e,f,g,h,k,m){m=void 0!==m?m:1026;if(1026!==m&&1027!==m)throw Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat");void 0===c&&1026===m&&(c=1012);void 0===c&&1027===m&&(c=1020);ba.call(this,null,d,e,f,g,h,m,c,k);this.image={width:a,
-height:b};this.magFilter=void 0!==g?g:1003;this.minFilter=void 0!==h?h:1003;this.generateMipmaps=this.flipY=!1}function Mb(a){E.call(this);this.type="WireframeGeometry";var b=[],c,d,e,f,g=[0,0],h={},k,m,q=["a","b","c"];if(a&&a.isGeometry){var v=a.faces;c=0;for(e=v.length;c<e;c++){var p=v[c];for(d=0;3>d;d++)k=p[q[d]],m=p[q[(d+1)%3]],g[0]=Math.min(k,m),g[1]=Math.max(k,m),k=g[0]+","+g[1],void 0===h[k]&&(h[k]={index1:g[0],index2:g[1]})}for(k in h)c=h[k],q=a.vertices[c.index1],b.push(q.x,q.y,q.z),q=a.vertices[c.index2],
-b.push(q.x,q.y,q.z)}else if(a&&a.isBufferGeometry){var r,q=new n;if(null!==a.index){v=a.attributes.position;p=a.index;r=a.groups;0===r.length&&(r=[{start:0,count:p.count,materialIndex:0}]);a=0;for(f=r.length;a<f;++a)for(c=r[a],d=c.start,e=c.count,c=d,e=d+e;c<e;c+=3)for(d=0;3>d;d++)k=p.getX(c+d),m=p.getX(c+(d+1)%3),g[0]=Math.min(k,m),g[1]=Math.max(k,m),k=g[0]+","+g[1],void 0===h[k]&&(h[k]={index1:g[0],index2:g[1]});for(k in h)c=h[k],q.fromBufferAttribute(v,c.index1),b.push(q.x,q.y,q.z),q.fromBufferAttribute(v,
-c.index2),b.push(q.x,q.y,q.z)}else for(v=a.attributes.position,c=0,e=v.count/3;c<e;c++)for(d=0;3>d;d++)h=3*c+d,q.fromBufferAttribute(v,h),b.push(q.x,q.y,q.z),h=3*c+(d+1)%3,q.fromBufferAttribute(v,h),b.push(q.x,q.y,q.z)}this.addAttribute("position",new B(b,3))}function Cc(a,b,c){J.call(this);this.type="ParametricGeometry";this.parameters={func:a,slices:b,stacks:c};this.fromBufferGeometry(new Nb(a,b,c));this.mergeVertices()}function Nb(a,b,c){E.call(this);this.type="ParametricBufferGeometry";this.parameters=
-{func:a,slices:b,stacks:c};var d=[],e=[],f=[],g=[],h=new n,k=new n,m=new n,q=new n,v=new n,p,r,l=b+1;for(p=0;p<=c;p++){var t=p/c;for(r=0;r<=b;r++){var y=r/b,k=a(y,t,k);e.push(k.x,k.y,k.z);0<=y-1E-5?(m=a(y-1E-5,t,m),q.subVectors(k,m)):(m=a(y+1E-5,t,m),q.subVectors(m,k));0<=t-1E-5?(m=a(y,t-1E-5,m),v.subVectors(k,m)):(m=a(y,t+1E-5,m),v.subVectors(m,k));h.crossVectors(q,v).normalize();f.push(h.x,h.y,h.z);g.push(y,t)}}for(p=0;p<c;p++)for(r=0;r<b;r++)a=p*l+r+1,h=(p+1)*l+r+1,k=(p+1)*l+r,d.push(p*l+r,a,k),
-d.push(a,h,k);this.setIndex(d);this.addAttribute("position",new B(e,3));this.addAttribute("normal",new B(f,3));this.addAttribute("uv",new B(g,2))}function Dc(a,b,c,d){J.call(this);this.type="PolyhedronGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};this.fromBufferGeometry(new za(a,b,c,d));this.mergeVertices()}function za(a,b,c,d){function e(a){h.push(a.x,a.y,a.z)}function f(b,c){var d=3*b;c.x=a[d+0];c.y=a[d+1];c.z=a[d+2]}function g(a,b,c,d){0>d&&1===a.x&&(k[b]=a.x-1);0===c.x&&0===
-c.z&&(k[b]=d/2/Math.PI+.5)}E.call(this);this.type="PolyhedronBufferGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;var h=[],k=[];(function(a){for(var c=new n,d=new n,g=new n,h=0;h<b.length;h+=3){f(b[h+0],c);f(b[h+1],d);f(b[h+2],g);var k=c,l=d,y=g,x=Math.pow(2,a),u=[],H,w;for(H=0;H<=x;H++){u[H]=[];var I=k.clone().lerp(y,H/x),W=l.clone().lerp(y,H/x),D=x-H;for(w=0;w<=D;w++)u[H][w]=0===w&&H===x?I:I.clone().lerp(W,w/D)}for(H=0;H<x;H++)for(w=0;w<2*(x-H)-1;w++)k=Math.floor(w/
-2),0===w%2?(e(u[H][k+1]),e(u[H+1][k]),e(u[H][k])):(e(u[H][k+1]),e(u[H+1][k+1]),e(u[H+1][k]))}})(d);(function(a){for(var b=new n,c=0;c<h.length;c+=3)b.x=h[c+0],b.y=h[c+1],b.z=h[c+2],b.normalize().multiplyScalar(a),h[c+0]=b.x,h[c+1]=b.y,h[c+2]=b.z})(c);(function(){for(var a=new n,b=0;b<h.length;b+=3)a.x=h[b+0],a.y=h[b+1],a.z=h[b+2],k.push(Math.atan2(a.z,-a.x)/2/Math.PI+.5,1-(Math.atan2(-a.y,Math.sqrt(a.x*a.x+a.z*a.z))/Math.PI+.5));for(var a=new n,b=new n,c=new n,d=new n,e=new C,f=new C,l=new C,y=0,
-x=0;y<h.length;y+=9,x+=6){a.set(h[y+0],h[y+1],h[y+2]);b.set(h[y+3],h[y+4],h[y+5]);c.set(h[y+6],h[y+7],h[y+8]);e.set(k[x+0],k[x+1]);f.set(k[x+2],k[x+3]);l.set(k[x+4],k[x+5]);d.copy(a).add(b).add(c).divideScalar(3);var u=Math.atan2(d.z,-d.x);g(e,x+0,a,u);g(f,x+2,b,u);g(l,x+4,c,u)}for(a=0;a<k.length;a+=6)b=k[a+0],c=k[a+2],d=k[a+4],e=Math.min(b,c,d),.9<Math.max(b,c,d)&&.1>e&&(.2>b&&(k[a+0]+=1),.2>c&&(k[a+2]+=1),.2>d&&(k[a+4]+=1))})();this.addAttribute("position",new B(h,3));this.addAttribute("normal",
-new B(h.slice(),3));this.addAttribute("uv",new B(k,2));0===d?this.computeVertexNormals():this.normalizeNormals()}function Ec(a,b){J.call(this);this.type="TetrahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Ob(a,b));this.mergeVertices()}function Ob(a,b){za.call(this,[1,1,1,-1,-1,1,-1,1,-1,1,-1,-1],[2,1,0,0,3,2,1,3,0,2,3,1],a,b);this.type="TetrahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Fc(a,b){J.call(this);this.type="OctahedronGeometry";this.parameters=
-{radius:a,detail:b};this.fromBufferGeometry(new lb(a,b));this.mergeVertices()}function lb(a,b){za.call(this,[1,0,0,-1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1],[0,2,4,0,4,3,0,3,5,0,5,2,1,2,5,1,5,3,1,3,4,1,4,2],a,b);this.type="OctahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Gc(a,b){J.call(this);this.type="IcosahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Pb(a,b));this.mergeVertices()}function Pb(a,b){var c=(1+Math.sqrt(5))/2;za.call(this,[-1,c,0,1,c,0,
--1,-c,0,1,-c,0,0,-1,c,0,1,c,0,-1,-c,0,1,-c,c,0,-1,c,0,1,-c,0,-1,-c,0,1],[0,11,5,0,5,1,0,1,7,0,7,10,0,10,11,1,5,9,5,11,4,11,10,2,10,7,6,7,1,8,3,9,4,3,4,2,3,2,6,3,6,8,3,8,9,4,9,5,2,4,11,6,2,10,8,6,7,9,8,1],a,b);this.type="IcosahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Hc(a,b){J.call(this);this.type="DodecahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Qb(a,b));this.mergeVertices()}function Qb(a,b){var c=(1+Math.sqrt(5))/2,d=1/c;za.call(this,
-[-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-d,-c,0,-d,c,0,d,-c,0,d,c,-d,-c,0,-d,c,0,d,-c,0,d,c,0,-c,0,-d,c,0,-d,-c,0,d,c,0,d],[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2,6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,12,14,1,14,5,1,5,9],a,b);this.type="DodecahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Ic(a,
-b,c,d,e,f){J.call(this);this.type="TubeGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};void 0!==f&&console.warn("THREE.TubeGeometry: taper has been removed.");a=new Rb(a,b,c,d,e);this.tangents=a.tangents;this.normals=a.normals;this.binormals=a.binormals;this.fromBufferGeometry(a);this.mergeVertices()}function Rb(a,b,c,d,e){function f(e){var f=a.getPointAt(e/b),m=g.normals[e];e=g.binormals[e];for(v=0;v<=d;v++){var q=v/d*Math.PI*2,l=Math.sin(q),q=-Math.cos(q);
-k.x=q*m.x+l*e.x;k.y=q*m.y+l*e.y;k.z=q*m.z+l*e.z;k.normalize();r.push(k.x,k.y,k.z);h.x=f.x+c*k.x;h.y=f.y+c*k.y;h.z=f.z+c*k.z;p.push(h.x,h.y,h.z)}}E.call(this);this.type="TubeBufferGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};b=b||64;c=c||1;d=d||8;e=e||!1;var g=a.computeFrenetFrames(b,e);this.tangents=g.tangents;this.normals=g.normals;this.binormals=g.binormals;var h=new n,k=new n,m=new C,q,v,p=[],r=[],l=[],t=[];for(q=0;q<b;q++)f(q);f(!1===e?b:0);for(q=0;q<=
-b;q++)for(v=0;v<=d;v++)m.x=q/b,m.y=v/d,l.push(m.x,m.y);(function(){for(v=1;v<=b;v++)for(q=1;q<=d;q++){var a=(d+1)*v+(q-1),c=(d+1)*v+q,e=(d+1)*(v-1)+q;t.push((d+1)*(v-1)+(q-1),a,e);t.push(a,c,e)}})();this.setIndex(t);this.addAttribute("position",new B(p,3));this.addAttribute("normal",new B(r,3));this.addAttribute("uv",new B(l,2))}function Jc(a,b,c,d,e,f,g){J.call(this);this.type="TorusKnotGeometry";this.parameters={radius:a,tube:b,tubularSegments:c,radialSegments:d,p:e,q:f};void 0!==g&&console.warn("THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.");
-this.fromBufferGeometry(new Sb(a,b,c,d,e,f));this.mergeVertices()}function Sb(a,b,c,d,e,f){function g(a,b,c,d,e){var f=Math.sin(a);b=c/b*a;c=Math.cos(b);e.x=d*(2+c)*.5*Math.cos(a);e.y=d*(2+c)*f*.5;e.z=d*Math.sin(b)*.5}E.call(this);this.type="TorusKnotBufferGeometry";this.parameters={radius:a,tube:b,tubularSegments:c,radialSegments:d,p:e,q:f};a=a||100;b=b||40;c=Math.floor(c)||64;d=Math.floor(d)||8;e=e||2;f=f||3;var h=[],k=[],m=[],q=[],v,p,r=new n,l=new n,t=new n,y=new n,x=new n,u=new n,H=new n;for(v=
-0;v<=c;++v)for(p=v/c*e*Math.PI*2,g(p,e,f,a,t),g(p+.01,e,f,a,y),u.subVectors(y,t),H.addVectors(y,t),x.crossVectors(u,H),H.crossVectors(x,u),x.normalize(),H.normalize(),p=0;p<=d;++p){var w=p/d*Math.PI*2,I=-b*Math.cos(w),w=b*Math.sin(w);r.x=t.x+(I*H.x+w*x.x);r.y=t.y+(I*H.y+w*x.y);r.z=t.z+(I*H.z+w*x.z);k.push(r.x,r.y,r.z);l.subVectors(r,t).normalize();m.push(l.x,l.y,l.z);q.push(v/c);q.push(p/d)}for(p=1;p<=c;p++)for(v=1;v<=d;v++)a=(d+1)*p+(v-1),b=(d+1)*p+v,e=(d+1)*(p-1)+v,h.push((d+1)*(p-1)+(v-1),a,e),
-h.push(a,b,e);this.setIndex(h);this.addAttribute("position",new B(k,3));this.addAttribute("normal",new B(m,3));this.addAttribute("uv",new B(q,2))}function Kc(a,b,c,d,e){J.call(this);this.type="TorusGeometry";this.parameters={radius:a,tube:b,radialSegments:c,tubularSegments:d,arc:e};this.fromBufferGeometry(new Tb(a,b,c,d,e));this.mergeVertices()}function Tb(a,b,c,d,e){E.call(this);this.type="TorusBufferGeometry";this.parameters={radius:a,tube:b,radialSegments:c,tubularSegments:d,arc:e};a=a||100;b=
-b||40;c=Math.floor(c)||8;d=Math.floor(d)||6;e=e||2*Math.PI;var f=[],g=[],h=[],k=[],m=new n,q=new n,v=new n,p,r;for(p=0;p<=c;p++)for(r=0;r<=d;r++){var l=r/d*e,t=p/c*Math.PI*2;q.x=(a+b*Math.cos(t))*Math.cos(l);q.y=(a+b*Math.cos(t))*Math.sin(l);q.z=b*Math.sin(t);g.push(q.x,q.y,q.z);m.x=a*Math.cos(l);m.y=a*Math.sin(l);v.subVectors(q,m).normalize();h.push(v.x,v.y,v.z);k.push(r/d);k.push(p/c)}for(p=1;p<=c;p++)for(r=1;r<=d;r++)a=(d+1)*(p-1)+r-1,b=(d+1)*(p-1)+r,e=(d+1)*p+r,f.push((d+1)*p+r-1,a,e),f.push(a,
-b,e);this.setIndex(f);this.addAttribute("position",new B(g,3));this.addAttribute("normal",new B(h,3));this.addAttribute("uv",new B(k,2))}function cb(a,b){J.call(this);this.type="ExtrudeGeometry";this.parameters={shapes:a,options:b};this.fromBufferGeometry(new Ga(a,b));this.mergeVertices()}function Ga(a,b){"undefined"!==typeof a&&(E.call(this),this.type="ExtrudeBufferGeometry",a=Array.isArray(a)?a:[a],this.addShapeList(a,b),this.computeVertexNormals())}function Lc(a,b){J.call(this);this.type="TextGeometry";
-this.parameters={text:a,parameters:b};this.fromBufferGeometry(new Ub(a,b));this.mergeVertices()}function Ub(a,b){b=b||{};var c=b.font;if(!c||!c.isFont)return console.error("THREE.TextGeometry: font parameter is not an instance of THREE.Font."),new J;c=c.generateShapes(a,b.size,b.curveSegments);b.amount=void 0!==b.height?b.height:50;void 0===b.bevelThickness&&(b.bevelThickness=10);void 0===b.bevelSize&&(b.bevelSize=8);void 0===b.bevelEnabled&&(b.bevelEnabled=!1);Ga.call(this,c,b);this.type="TextBufferGeometry"}
-function Mc(a,b,c,d,e,f,g){J.call(this);this.type="SphereGeometry";this.parameters={radius:a,widthSegments:b,heightSegments:c,phiStart:d,phiLength:e,thetaStart:f,thetaLength:g};this.fromBufferGeometry(new mb(a,b,c,d,e,f,g));this.mergeVertices()}function mb(a,b,c,d,e,f,g){E.call(this);this.type="SphereBufferGeometry";this.parameters={radius:a,widthSegments:b,heightSegments:c,phiStart:d,phiLength:e,thetaStart:f,thetaLength:g};a=a||50;b=Math.max(3,Math.floor(b)||8);c=Math.max(2,Math.floor(c)||6);d=void 0!==
-d?d:0;e=void 0!==e?e:2*Math.PI;f=void 0!==f?f:0;g=void 0!==g?g:Math.PI;var h=f+g,k,m,q=0,v=[],p=new n,r=new n,l=[],t=[],y=[],x=[];for(m=0;m<=c;m++){var u=[],H=m/c;for(k=0;k<=b;k++){var w=k/b;p.x=-a*Math.cos(d+w*e)*Math.sin(f+H*g);p.y=a*Math.cos(f+H*g);p.z=a*Math.sin(d+w*e)*Math.sin(f+H*g);t.push(p.x,p.y,p.z);r.set(p.x,p.y,p.z).normalize();y.push(r.x,r.y,r.z);x.push(w,1-H);u.push(q++)}v.push(u)}for(m=0;m<c;m++)for(k=0;k<b;k++)a=v[m][k+1],d=v[m][k],e=v[m+1][k],g=v[m+1][k+1],(0!==m||0<f)&&l.push(a,d,
-g),(m!==c-1||h<Math.PI)&&l.push(d,e,g);this.setIndex(l);this.addAttribute("position",new B(t,3));this.addAttribute("normal",new B(y,3));this.addAttribute("uv",new B(x,2))}function Nc(a,b,c,d,e,f){J.call(this);this.type="RingGeometry";this.parameters={innerRadius:a,outerRadius:b,thetaSegments:c,phiSegments:d,thetaStart:e,thetaLength:f};this.fromBufferGeometry(new Vb(a,b,c,d,e,f));this.mergeVertices()}function Vb(a,b,c,d,e,f){E.call(this);this.type="RingBufferGeometry";this.parameters={innerRadius:a,
-outerRadius:b,thetaSegments:c,phiSegments:d,thetaStart:e,thetaLength:f};a=a||20;b=b||50;e=void 0!==e?e:0;f=void 0!==f?f:2*Math.PI;c=void 0!==c?Math.max(3,c):8;d=void 0!==d?Math.max(1,d):1;var g=[],h=[],k=[],m=[],q=a,v=(b-a)/d,p=new n,r=new C,l,t;for(l=0;l<=d;l++){for(t=0;t<=c;t++)a=e+t/c*f,p.x=q*Math.cos(a),p.y=q*Math.sin(a),h.push(p.x,p.y,p.z),k.push(0,0,1),r.x=(p.x/b+1)/2,r.y=(p.y/b+1)/2,m.push(r.x,r.y);q+=v}for(l=0;l<d;l++)for(b=l*(c+1),t=0;t<c;t++)a=t+b,e=a+c+1,f=a+c+2,q=a+1,g.push(a,e,q),g.push(e,
-f,q);this.setIndex(g);this.addAttribute("position",new B(h,3));this.addAttribute("normal",new B(k,3));this.addAttribute("uv",new B(m,2))}function Oc(a,b,c,d){J.call(this);this.type="LatheGeometry";this.parameters={points:a,segments:b,phiStart:c,phiLength:d};this.fromBufferGeometry(new Wb(a,b,c,d));this.mergeVertices()}function Wb(a,b,c,d){E.call(this);this.type="LatheBufferGeometry";this.parameters={points:a,segments:b,phiStart:c,phiLength:d};b=Math.floor(b)||12;c=c||0;d=d||2*Math.PI;d=Y.clamp(d,
-0,2*Math.PI);var e=[],f=[],g=[],h=1/b,k=new n,m=new C,q,v;for(q=0;q<=b;q++){v=c+q*h*d;var p=Math.sin(v),r=Math.cos(v);for(v=0;v<=a.length-1;v++)k.x=a[v].x*p,k.y=a[v].y,k.z=a[v].x*r,f.push(k.x,k.y,k.z),m.x=q/b,m.y=v/(a.length-1),g.push(m.x,m.y)}for(q=0;q<b;q++)for(v=0;v<a.length-1;v++)c=v+q*a.length,h=c+a.length,k=c+a.length+1,m=c+1,e.push(c,h,m),e.push(h,k,m);this.setIndex(e);this.addAttribute("position",new B(f,3));this.addAttribute("uv",new B(g,2));this.computeVertexNormals();if(d===2*Math.PI)for(d=
-this.attributes.normal.array,e=new n,f=new n,g=new n,c=b*a.length*3,v=q=0;q<a.length;q++,v+=3)e.x=d[v+0],e.y=d[v+1],e.z=d[v+2],f.x=d[c+v+0],f.y=d[c+v+1],f.z=d[c+v+2],g.addVectors(e,f).normalize(),d[v+0]=d[c+v+0]=g.x,d[v+1]=d[c+v+1]=g.y,d[v+2]=d[c+v+2]=g.z}function Xb(a,b){J.call(this);this.type="ShapeGeometry";"object"===typeof b&&(console.warn("THREE.ShapeGeometry: Options parameter has been removed."),b=b.curveSegments);this.parameters={shapes:a,curveSegments:b};this.fromBufferGeometry(new Yb(a,
-b));this.mergeVertices()}function Yb(a,b){function c(a){var c,h,m=e.length/3;a=a.extractPoints(b);var l=a.shape,n=a.holes;if(!1===Ia.isClockWise(l))for(l=l.reverse(),a=0,c=n.length;a<c;a++)h=n[a],!0===Ia.isClockWise(h)&&(n[a]=h.reverse());var y=Ia.triangulateShape(l,n);a=0;for(c=n.length;a<c;a++)h=n[a],l=l.concat(h);a=0;for(c=l.length;a<c;a++)h=l[a],e.push(h.x,h.y,0),f.push(0,0,1),g.push(h.x,h.y);a=0;for(c=y.length;a<c;a++)l=y[a],d.push(l[0]+m,l[1]+m,l[2]+m),k+=3}E.call(this);this.type="ShapeBufferGeometry";
-this.parameters={shapes:a,curveSegments:b};b=b||12;var d=[],e=[],f=[],g=[],h=0,k=0;if(!1===Array.isArray(a))c(a);else for(var m=0;m<a.length;m++)c(a[m]),this.addGroup(h,k,m),h+=k,k=0;this.setIndex(d);this.addAttribute("position",new B(e,3));this.addAttribute("normal",new B(f,3));this.addAttribute("uv",new B(g,2))}function Zb(a,b){E.call(this);this.type="EdgesGeometry";this.parameters={thresholdAngle:b};var c=[],d=Math.cos(Y.DEG2RAD*(void 0!==b?b:1)),e=[0,0],f={},g,h,k=["a","b","c"],m;a.isBufferGeometry?
-(m=new J,m.fromBufferGeometry(a)):m=a.clone();m.mergeVertices();m.computeFaceNormals();var q=m.vertices;m=m.faces;for(var v=0,p=m.length;v<p;v++)for(var l=m[v],n=0;3>n;n++)g=l[k[n]],h=l[k[(n+1)%3]],e[0]=Math.min(g,h),e[1]=Math.max(g,h),g=e[0]+","+e[1],void 0===f[g]?f[g]={index1:e[0],index2:e[1],face1:v,face2:void 0}:f[g].face2=v;for(g in f)if(e=f[g],void 0===e.face2||m[e.face1].normal.dot(m[e.face2].normal)<=d)k=q[e.index1],c.push(k.x,k.y,k.z),k=q[e.index2],c.push(k.x,k.y,k.z);this.addAttribute("position",
-new B(c,3))}function nb(a,b,c,d,e,f,g,h){J.call(this);this.type="CylinderGeometry";this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:h};this.fromBufferGeometry(new Ua(a,b,c,d,e,f,g,h));this.mergeVertices()}function Ua(a,b,c,d,e,f,g,h){function k(c){var e,f,k,t=new C,D=new n,O=0,aa=!0===c?a:b,F=!0===c?1:-1;f=ca;for(e=1;e<=d;e++)v.push(0,y*F,0),p.push(0,F,0),l.push(.5,.5),ca++;k=ca;for(e=0;e<=d;e++){var B=e/d*h+g,z=Math.cos(B),
-B=Math.sin(B);D.x=aa*B;D.y=y*F;D.z=aa*z;v.push(D.x,D.y,D.z);p.push(0,F,0);t.x=.5*z+.5;t.y=.5*B*F+.5;l.push(t.x,t.y);ca++}for(e=0;e<d;e++)t=f+e,D=k+e,!0===c?q.push(D,D+1,t):q.push(D+1,D,t),O+=3;m.addGroup(x,O,!0===c?1:2);x+=O}E.call(this);this.type="CylinderBufferGeometry";this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:h};var m=this;a=void 0!==a?a:20;b=void 0!==b?b:20;c=void 0!==c?c:100;d=Math.floor(d)||8;e=Math.floor(e)||
-1;f=void 0!==f?f:!1;g=void 0!==g?g:0;h=void 0!==h?h:2*Math.PI;var q=[],v=[],p=[],l=[],ca=0,t=[],y=c/2,x=0;(function(){var f,k,w=new n,I=new n,W=0,D=(b-a)/c;for(k=0;k<=e;k++){var O=[],aa=k/e,F=aa*(b-a)+a;for(f=0;f<=d;f++){var B=f/d,C=B*h+g,z=Math.sin(C),C=Math.cos(C);I.x=F*z;I.y=-aa*c+y;I.z=F*C;v.push(I.x,I.y,I.z);w.set(z,D,C).normalize();p.push(w.x,w.y,w.z);l.push(B,1-aa);O.push(ca++)}t.push(O)}for(f=0;f<d;f++)for(k=0;k<e;k++)w=t[k+1][f],I=t[k+1][f+1],D=t[k][f+1],q.push(t[k][f],w,D),q.push(w,I,D),
-W+=6;m.addGroup(x,W,0);x+=W})();!1===f&&(0<a&&k(!0),0<b&&k(!1));this.setIndex(q);this.addAttribute("position",new B(v,3));this.addAttribute("normal",new B(p,3));this.addAttribute("uv",new B(l,2))}function Pc(a,b,c,d,e,f,g){nb.call(this,0,a,b,c,d,e,f,g);this.type="ConeGeometry";this.parameters={radius:a,height:b,radialSegments:c,heightSegments:d,openEnded:e,thetaStart:f,thetaLength:g}}function Qc(a,b,c,d,e,f,g){Ua.call(this,0,a,b,c,d,e,f,g);this.type="ConeBufferGeometry";this.parameters={radius:a,
-height:b,radialSegments:c,heightSegments:d,openEnded:e,thetaStart:f,thetaLength:g}}function Rc(a,b,c,d){J.call(this);this.type="CircleGeometry";this.parameters={radius:a,segments:b,thetaStart:c,thetaLength:d};this.fromBufferGeometry(new $b(a,b,c,d));this.mergeVertices()}function $b(a,b,c,d){E.call(this);this.type="CircleBufferGeometry";this.parameters={radius:a,segments:b,thetaStart:c,thetaLength:d};a=a||50;b=void 0!==b?Math.max(3,b):8;c=void 0!==c?c:0;d=void 0!==d?d:2*Math.PI;var e=[],f=[],g=[],
-h=[],k,m,q=new n,v=new C;f.push(0,0,0);g.push(0,0,1);h.push(.5,.5);m=0;for(k=3;m<=b;m++,k+=3){var p=c+m/b*d;q.x=a*Math.cos(p);q.y=a*Math.sin(p);f.push(q.x,q.y,q.z);g.push(0,0,1);v.x=(f[k]/a+1)/2;v.y=(f[k+1]/a+1)/2;h.push(v.x,v.y)}for(k=1;k<=b;k++)e.push(k,k+1,0);this.setIndex(e);this.addAttribute("position",new B(f,3));this.addAttribute("normal",new B(g,3));this.addAttribute("uv",new B(h,2))}function ac(a){ra.call(this,{uniforms:Ca.merge([R.lights,{opacity:{value:1}}]),vertexShader:X.shadow_vert,
-fragmentShader:X.shadow_frag});this.transparent=this.lights=!0;Object.defineProperties(this,{opacity:{enumerable:!0,get:function(){return this.uniforms.opacity.value},set:function(a){this.uniforms.opacity.value=a}}});this.setValues(a)}function bc(a){ra.call(this,a);this.type="RawShaderMaterial"}function Pa(a){U.call(this);this.defines={STANDARD:""};this.type="MeshStandardMaterial";this.color=new G(16777215);this.metalness=this.roughness=.5;this.lightMap=this.map=null;this.lightMapIntensity=1;this.aoMap=
-null;this.aoMapIntensity=1;this.emissive=new G(0);this.emissiveIntensity=1;this.bumpMap=this.emissiveMap=null;this.bumpScale=1;this.normalMap=null;this.normalScale=new C(1,1);this.displacementMap=null;this.displacementScale=1;this.displacementBias=0;this.envMap=this.alphaMap=this.metalnessMap=this.roughnessMap=null;this.envMapIntensity=1;this.refractionRatio=.98;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap="round";this.morphNormals=this.morphTargets=this.skinning=
-!1;this.setValues(a)}function ob(a){Pa.call(this);this.defines={PHYSICAL:""};this.type="MeshPhysicalMaterial";this.reflectivity=.5;this.clearCoatRoughness=this.clearCoat=0;this.setValues(a)}function Ja(a){U.call(this);this.type="MeshPhongMaterial";this.color=new G(16777215);this.specular=new G(1118481);this.shininess=30;this.lightMap=this.map=null;this.lightMapIntensity=1;this.aoMap=null;this.aoMapIntensity=1;this.emissive=new G(0);this.emissiveIntensity=1;this.bumpMap=this.emissiveMap=null;this.bumpScale=
-1;this.normalMap=null;this.normalScale=new C(1,1);this.displacementMap=null;this.displacementScale=1;this.displacementBias=0;this.envMap=this.alphaMap=this.specularMap=null;this.combine=0;this.reflectivity=1;this.refractionRatio=.98;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap="round";this.morphNormals=this.morphTargets=this.skinning=!1;this.setValues(a)}function pb(a){Ja.call(this);this.defines={TOON:""};this.type="MeshToonMaterial";this.gradientMap=null;
-this.setValues(a)}function qb(a){U.call(this);this.type="MeshNormalMaterial";this.bumpMap=null;this.bumpScale=1;this.normalMap=null;this.normalScale=new C(1,1);this.displacementMap=null;this.displacementScale=1;this.displacementBias=0;this.wireframe=!1;this.wireframeLinewidth=1;this.morphNormals=this.morphTargets=this.skinning=this.lights=this.fog=!1;this.setValues(a)}function rb(a){U.call(this);this.type="MeshLambertMaterial";this.color=new G(16777215);this.lightMap=this.map=null;this.lightMapIntensity=
-1;this.aoMap=null;this.aoMapIntensity=1;this.emissive=new G(0);this.emissiveIntensity=1;this.envMap=this.alphaMap=this.specularMap=this.emissiveMap=null;this.combine=0;this.reflectivity=1;this.refractionRatio=.98;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap="round";this.morphNormals=this.morphTargets=this.skinning=!1;this.setValues(a)}function sb(a){U.call(this);this.type="LineDashedMaterial";this.color=new G(16777215);this.scale=this.linewidth=1;this.dashSize=
-3;this.gapSize=1;this.lights=!1;this.setValues(a)}function Zd(a,b,c){var d=this,e=!1,f=0,g=0;this.onStart=void 0;this.onLoad=a;this.onProgress=b;this.onError=c;this.itemStart=function(a){g++;if(!1===e&&void 0!==d.onStart)d.onStart(a,f,g);e=!0};this.itemEnd=function(a){f++;if(void 0!==d.onProgress)d.onProgress(a,f,g);if(f===g&&(e=!1,void 0!==d.onLoad))d.onLoad()};this.itemError=function(a){if(void 0!==d.onError)d.onError(a)}}function Ka(a){this.manager=void 0!==a?a:va}function Oe(a){this.manager=void 0!==
-a?a:va;this._parser=null}function $d(a){this.manager=void 0!==a?a:va;this._parser=null}function Sc(a){this.manager=void 0!==a?a:va}function ae(a){this.manager=void 0!==a?a:va}function rd(a){this.manager=void 0!==a?a:va}function na(a,b){z.call(this);this.type="Light";this.color=new G(a);this.intensity=void 0!==b?b:1;this.receiveShadow=void 0}function sd(a,b,c){na.call(this,a,c);this.type="HemisphereLight";this.castShadow=void 0;this.position.copy(z.DefaultUp);this.updateMatrix();this.groundColor=new G(b)}
-function tb(a){this.camera=a;this.bias=0;this.radius=1;this.mapSize=new C(512,512);this.map=null;this.matrix=new K}function td(){tb.call(this,new qa(50,1,.5,500))}function ud(a,b,c,d,e,f){na.call(this,a,b);this.type="SpotLight";this.position.copy(z.DefaultUp);this.updateMatrix();this.target=new z;Object.defineProperty(this,"power",{get:function(){return this.intensity*Math.PI},set:function(a){this.intensity=a/Math.PI}});this.distance=void 0!==c?c:0;this.angle=void 0!==d?d:Math.PI/3;this.penumbra=
-void 0!==e?e:0;this.decay=void 0!==f?f:1;this.shadow=new td}function vd(a,b,c,d){na.call(this,a,b);this.type="PointLight";Object.defineProperty(this,"power",{get:function(){return 4*this.intensity*Math.PI},set:function(a){this.intensity=a/(4*Math.PI)}});this.distance=void 0!==c?c:0;this.decay=void 0!==d?d:1;this.shadow=new tb(new qa(90,1,.5,500))}function wd(){tb.call(this,new Fb(-5,5,5,-5,.5,500))}function xd(a,b){na.call(this,a,b);this.type="DirectionalLight";this.position.copy(z.DefaultUp);this.updateMatrix();
-this.target=new z;this.shadow=new wd}function yd(a,b){na.call(this,a,b);this.type="AmbientLight";this.castShadow=void 0}function zd(a,b,c,d){na.call(this,a,b);this.type="RectAreaLight";this.position.set(0,1,0);this.updateMatrix();this.width=void 0!==c?c:10;this.height=void 0!==d?d:10}function wa(a,b,c,d){this.parameterPositions=a;this._cachedIndex=0;this.resultBuffer=void 0!==d?d:new b.constructor(c);this.sampleValues=b;this.valueSize=c}function Ad(a,b,c,d){wa.call(this,a,b,c,d);this._offsetNext=
-this._weightNext=this._offsetPrev=this._weightPrev=-0}function Tc(a,b,c,d){wa.call(this,a,b,c,d)}function Bd(a,b,c,d){wa.call(this,a,b,c,d)}function ub(a,b,c,d){if(void 0===a)throw Error("track name is undefined");if(void 0===b||0===b.length)throw Error("no keyframes in track named "+a);this.name=a;this.times=ia.convertArray(b,this.TimeBufferType);this.values=ia.convertArray(c,this.ValueBufferType);this.setInterpolation(d||this.DefaultInterpolation);this.validate();this.optimize()}function cc(a,b,
-c,d){ub.call(this,a,b,c,d)}function Cd(a,b,c,d){wa.call(this,a,b,c,d)}function Uc(a,b,c,d){ub.call(this,a,b,c,d)}function dc(a,b,c,d){ub.call(this,a,b,c,d)}function Dd(a,b,c,d){ub.call(this,a,b,c,d)}function Ed(a,b,c){ub.call(this,a,b,c)}function Fd(a,b,c,d){ub.call(this,a,b,c,d)}function vb(a,b,c,d){ub.apply(this,arguments)}function Da(a,b,c){this.name=a;this.tracks=c;this.duration=void 0!==b?b:-1;this.uuid=Y.generateUUID();0>this.duration&&this.resetDuration();this.optimize()}function Gd(a){this.manager=
-void 0!==a?a:va;this.textures={}}function be(a){this.manager=void 0!==a?a:va}function ec(){this.onLoadStart=function(){};this.onLoadProgress=function(){};this.onLoadComplete=function(){}}function ce(a){"boolean"===typeof a&&(console.warn("THREE.JSONLoader: showStatus parameter has been removed from constructor."),a=void 0);this.manager=void 0!==a?a:va;this.withCredentials=!1}function Pe(a){this.manager=void 0!==a?a:va;this.texturePath=""}function Qe(a,b,c,d,e){b=.5*(d-b);e=.5*(e-c);var f=a*a;return(2*
-c-2*d+b+e)*a*f+(-3*c+3*d-2*b-e)*f+b*a+c}function wb(a,b,c,d){var e=1-a;return e*e*b+2*(1-a)*a*c+a*a*d}function xb(a,b,c,d,e){var f=1-a,g=1-a;return f*f*f*b+3*g*g*a*c+3*(1-a)*a*a*d+a*a*a*e}function ua(){this.arcLengthDivisions=200}function Qa(a,b){this.arcLengthDivisions=200;this.v1=a;this.v2=b}function Vc(){this.arcLengthDivisions=200;this.curves=[];this.autoClose=!1}function Va(a,b,c,d,e,f,g,h){this.arcLengthDivisions=200;this.aX=a;this.aY=b;this.xRadius=c;this.yRadius=d;this.aStartAngle=e;this.aEndAngle=
-f;this.aClockwise=g;this.aRotation=h||0}function yb(a){this.arcLengthDivisions=200;this.points=void 0===a?[]:a}function fc(a,b,c,d){this.arcLengthDivisions=200;this.v0=a;this.v1=b;this.v2=c;this.v3=d}function gc(a,b,c){this.arcLengthDivisions=200;this.v0=a;this.v1=b;this.v2=c}function Wc(a){Vc.call(this);this.currentPoint=new C;a&&this.fromPoints(a)}function zb(){Wc.apply(this,arguments);this.holes=[]}function de(){this.subPaths=[];this.currentPath=null}function ee(a){this.data=a}function Re(a){this.manager=
-void 0!==a?a:va}function fe(a){this.manager=void 0!==a?a:va}function Se(){this.type="StereoCamera";this.aspect=1;this.eyeSep=.064;this.cameraL=new qa;this.cameraL.layers.enable(1);this.cameraL.matrixAutoUpdate=!1;this.cameraR=new qa;this.cameraR.layers.enable(2);this.cameraR.matrixAutoUpdate=!1}function Hd(a,b,c){z.call(this);this.type="CubeCamera";var d=new qa(90,1,a,b);d.up.set(0,-1,0);d.lookAt(new n(1,0,0));this.add(d);var e=new qa(90,1,a,b);e.up.set(0,-1,0);e.lookAt(new n(-1,0,0));this.add(e);
-var f=new qa(90,1,a,b);f.up.set(0,0,1);f.lookAt(new n(0,1,0));this.add(f);var g=new qa(90,1,a,b);g.up.set(0,0,-1);g.lookAt(new n(0,-1,0));this.add(g);var h=new qa(90,1,a,b);h.up.set(0,-1,0);h.lookAt(new n(0,0,1));this.add(h);var k=new qa(90,1,a,b);k.up.set(0,-1,0);k.lookAt(new n(0,0,-1));this.add(k);this.renderTarget=new Db(c,c,{format:1022,magFilter:1006,minFilter:1006});this.renderTarget.texture.name="CubeCamera";this.updateCubeMap=function(a,b){null===this.parent&&this.updateMatrixWorld();var c=
-this.renderTarget,p=c.texture.generateMipmaps;c.texture.generateMipmaps=!1;c.activeCubeFace=0;a.render(b,d,c);c.activeCubeFace=1;a.render(b,e,c);c.activeCubeFace=2;a.render(b,f,c);c.activeCubeFace=3;a.render(b,g,c);c.activeCubeFace=4;a.render(b,h,c);c.texture.generateMipmaps=p;c.activeCubeFace=5;a.render(b,k,c);a.setRenderTarget(null)}}function ge(){z.call(this);this.type="AudioListener";this.context=he.getContext();this.gain=this.context.createGain();this.gain.connect(this.context.destination);this.filter=
-null}function hc(a){z.call(this);this.type="Audio";this.context=a.context;this.gain=this.context.createGain();this.gain.connect(a.getInput());this.autoplay=!1;this.buffer=null;this.loop=!1;this.startTime=0;this.playbackRate=1;this.isPlaying=!1;this.hasPlaybackControl=!0;this.sourceType="empty";this.filters=[]}function ie(a){hc.call(this,a);this.panner=this.context.createPanner();this.panner.connect(this.gain)}function je(a,b){this.analyser=a.context.createAnalyser();this.analyser.fftSize=void 0!==
-b?b:2048;this.data=new Uint8Array(this.analyser.frequencyBinCount);a.getOutput().connect(this.analyser)}function ke(a,b,c){this.binding=a;this.valueSize=c;a=Float64Array;switch(b){case "quaternion":b=this._slerp;break;case "string":case "bool":a=Array;b=this._select;break;default:b=this._lerp}this.buffer=new a(4*c);this._mixBufferRegion=b;this.referenceCount=this.useCount=this.cumulativeWeight=0}function Te(a,b,c){c=c||ha.parseTrackName(b);this._targetGroup=a;this._bindings=a.subscribe_(b,c)}function ha(a,
-b,c){this.path=b;this.parsedPath=c||ha.parseTrackName(b);this.node=ha.findNode(a,this.parsedPath.nodeName)||a;this.rootNode=a}function Ue(a){this.uuid=Y.generateUUID();this._objects=Array.prototype.slice.call(arguments);this.nCachedObjects_=0;var b={};this._indicesByUUID=b;for(var c=0,d=arguments.length;c!==d;++c)b[arguments[c].uuid]=c;this._paths=[];this._parsedPaths=[];this._bindings=[];this._bindingsIndicesByPath={};var e=this;this.stats={objects:{get total(){return e._objects.length},get inUse(){return this.total-
-e.nCachedObjects_}},get bindingsPerObject(){return e._bindings.length}}}function Ve(a,b,c){this._mixer=a;this._clip=b;this._localRoot=c||null;a=b.tracks;b=a.length;c=Array(b);for(var d={endingStart:2400,endingEnd:2400},e=0;e!==b;++e){var f=a[e].createInterpolant(null);c[e]=f;f.settings=d}this._interpolantSettings=d;this._interpolants=c;this._propertyBindings=Array(b);this._weightInterpolant=this._timeScaleInterpolant=this._byClipCacheIndex=this._cacheIndex=null;this.loop=2201;this._loopCount=-1;this._startTime=
-null;this.time=0;this._effectiveWeight=this.weight=this._effectiveTimeScale=this.timeScale=1;this.repetitions=Infinity;this.paused=!1;this.enabled=!0;this.clampWhenFinished=!1;this.zeroSlopeAtEnd=this.zeroSlopeAtStart=!0}function We(a){this._root=a;this._initMemoryManager();this.time=this._accuIndex=0;this.timeScale=1}function Id(a,b){"string"===typeof a&&(console.warn("THREE.Uniform: Type parameter is no longer needed."),a=b);this.value=a}function le(){E.call(this);this.type="InstancedBufferGeometry";
-this.maxInstancedCount=void 0}function me(a,b,c,d){this.uuid=Y.generateUUID();this.data=a;this.itemSize=b;this.offset=c;this.normalized=!0===d}function ic(a,b){this.uuid=Y.generateUUID();this.array=a;this.stride=b;this.count=void 0!==a?a.length/b:0;this.dynamic=!1;this.updateRange={offset:0,count:-1};this.onUploadCallback=function(){};this.version=0}function ne(a,b,c){ic.call(this,a,b);this.meshPerAttribute=c||1}function oe(a,b,c){Z.call(this,a,b);this.meshPerAttribute=c||1}function Xe(a,b,c,d){this.ray=
-new kb(a,b);this.near=c||0;this.far=d||Infinity;this.params={Mesh:{},Line:{},LOD:{},Points:{threshold:1},Sprite:{}};Object.defineProperties(this.params,{PointCloud:{get:function(){console.warn("THREE.Raycaster: params.PointCloud has been renamed to params.Points.");return this.Points}}})}function Ye(a,b){return a.distance-b.distance}function pe(a,b,c,d){if(!1!==a.visible&&(a.raycast(b,c),!0===d)){a=a.children;d=0;for(var e=a.length;d<e;d++)pe(a[d],b,c,!0)}}function Ze(a){this.autoStart=void 0!==a?
-a:!0;this.elapsedTime=this.oldTime=this.startTime=0;this.running=!1}function $e(a,b,c){this.radius=void 0!==a?a:1;this.phi=void 0!==b?b:0;this.theta=void 0!==c?c:0;return this}function af(a,b,c){this.radius=void 0!==a?a:1;this.theta=void 0!==b?b:0;this.y=void 0!==c?c:0;return this}function ta(a,b){la.call(this,a,b);this.animationsMap={};this.animationsList=[];var c=this.geometry.morphTargets.length;this.createAnimation("__default",0,c-1,c/1);this.setAnimationWeight("__default",1)}function Xc(a){z.call(this);
-this.material=a;this.render=function(a){}}function Yc(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16711680;d=void 0!==d?d:1;b=0;(c=this.object.geometry)&&c.isGeometry?b=3*c.faces.length:c&&c.isBufferGeometry&&(b=c.attributes.normal.count);c=new E;b=new B(6*b,3);c.addAttribute("position",b);Q.call(this,c,new ea({color:a,linewidth:d}));this.matrixAutoUpdate=!1;this.update()}function jc(a){z.call(this);this.light=a;this.light.updateMatrixWorld();this.matrix=a.matrixWorld;this.matrixAutoUpdate=
-!1;a=new E;for(var b=[0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,-1,0,1,0,0,0,0,1,1,0,0,0,0,-1,1],c=0,d=1;32>c;c++,d++){var e=c/32*Math.PI*2,f=d/32*Math.PI*2;b.push(Math.cos(e),Math.sin(e),1,Math.cos(f),Math.sin(f),1)}a.addAttribute("position",new B(b,3));b=new ea({fog:!1});this.cone=new Q(a,b);this.add(this.cone);this.update()}function bf(a){var b=[];a&&a.isBone&&b.push(a);for(var c=0;c<a.children.length;c++)b.push.apply(b,bf(a.children[c]));return b}function kc(a){for(var b=bf(a),c=new E,d=[],e=[],f=new G(0,
-0,1),g=new G(0,1,0),h=0;h<b.length;h++){var k=b[h];k.parent&&k.parent.isBone&&(d.push(0,0,0),d.push(0,0,0),e.push(f.r,f.g,f.b),e.push(g.r,g.g,g.b))}c.addAttribute("position",new B(d,3));c.addAttribute("color",new B(e,3));d=new ea({vertexColors:2,depthTest:!1,depthWrite:!1,transparent:!0});Q.call(this,c,d);this.root=a;this.bones=b;this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;this.onBeforeRender()}function lc(a,b){this.light=a;this.light.updateMatrixWorld();var c=new mb(b,4,2),d=new ya({wireframe:!0,
-fog:!1});d.color.copy(this.light.color);la.call(this,c,d);this.matrix=this.light.matrixWorld;this.matrixAutoUpdate=!1}function mc(a){z.call(this);this.light=a;this.light.updateMatrixWorld();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;a=new ea({color:a.color});var b=new E;b.addAttribute("position",new Z(new Float32Array(15),3));this.add(new sa(b,a));this.update()}function nc(a,b){z.call(this);this.light=a;this.light.updateMatrixWorld();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;var c=
-new lb(b);c.rotateY(.5*Math.PI);var d=new ya({vertexColors:2,wireframe:!0}),e=c.getAttribute("position"),e=new Float32Array(3*e.count);c.addAttribute("color",new Z(e,3));this.add(new la(c,d));this.update()}function Zc(a,b,c,d){a=a||10;b=b||10;c=new G(void 0!==c?c:4473924);d=new G(void 0!==d?d:8947848);var e=b/2,f=a/b,g=a/2;a=[];for(var h=[],k=0,m=0,q=-g;k<=b;k++,q+=f){a.push(-g,0,q,g,0,q);a.push(q,0,-g,q,0,g);var l=k===e?c:d;l.toArray(h,m);m+=3;l.toArray(h,m);m+=3;l.toArray(h,m);m+=3;l.toArray(h,
-m);m+=3}b=new E;b.addAttribute("position",new B(a,3));b.addAttribute("color",new B(h,3));c=new ea({vertexColors:2});Q.call(this,b,c)}function Jd(a,b,c,d,e,f){a=a||10;b=b||16;c=c||8;d=d||64;e=new G(void 0!==e?e:4473924);f=new G(void 0!==f?f:8947848);var g=[],h=[],k,m,q,l,p;for(q=0;q<=b;q++)m=q/b*2*Math.PI,k=Math.sin(m)*a,m=Math.cos(m)*a,g.push(0,0,0),g.push(k,0,m),p=q&1?e:f,h.push(p.r,p.g,p.b),h.push(p.r,p.g,p.b);for(q=0;q<=c;q++)for(p=q&1?e:f,l=a-a/c*q,b=0;b<d;b++)m=b/d*2*Math.PI,k=Math.sin(m)*l,
-m=Math.cos(m)*l,g.push(k,0,m),h.push(p.r,p.g,p.b),m=(b+1)/d*2*Math.PI,k=Math.sin(m)*l,m=Math.cos(m)*l,g.push(k,0,m),h.push(p.r,p.g,p.b);a=new E;a.addAttribute("position",new B(g,3));a.addAttribute("color",new B(h,3));g=new ea({vertexColors:2});Q.call(this,a,g)}function $c(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16776960;d=void 0!==d?d:1;b=0;(c=this.object.geometry)&&c.isGeometry?b=c.faces.length:console.warn("THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.");
-c=new E;b=new B(6*b,3);c.addAttribute("position",b);Q.call(this,c,new ea({color:a,linewidth:d}));this.matrixAutoUpdate=!1;this.update()}function oc(a,b){z.call(this);this.light=a;this.light.updateMatrixWorld();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;void 0===b&&(b=1);var c=new E;c.addAttribute("position",new B([-b,b,0,b,b,0,b,-b,0,-b,-b,0,-b,b,0],3));var d=new ea({fog:!1});this.add(new sa(c,d));c=new E;c.addAttribute("position",new B([0,0,0,0,0,1],3));this.add(new sa(c,d));this.update()}
-function ad(a){function b(a,b,d){c(a,d);c(b,d)}function c(a,b){f.push(0,0,0);g.push(b.r,b.g,b.b);void 0===h[a]&&(h[a]=[]);h[a].push(f.length/3-1)}var d=new E,e=new ea({color:16777215,vertexColors:1}),f=[],g=[],h={},k=new G(16755200),m=new G(16711680),q=new G(43775),l=new G(16777215),p=new G(3355443);b("n1","n2",k);b("n2","n4",k);b("n4","n3",k);b("n3","n1",k);b("f1","f2",k);b("f2","f4",k);b("f4","f3",k);b("f3","f1",k);b("n1","f1",k);b("n2","f2",k);b("n3","f3",k);b("n4","f4",k);b("p","n1",m);b("p",
-"n2",m);b("p","n3",m);b("p","n4",m);b("u1","u2",q);b("u2","u3",q);b("u3","u1",q);b("c","t",l);b("p","c",p);b("cn1","cn2",p);b("cn3","cn4",p);b("cf1","cf2",p);b("cf3","cf4",p);d.addAttribute("position",new B(f,3));d.addAttribute("color",new B(g,3));Q.call(this,d,e);this.camera=a;this.camera.updateProjectionMatrix&&this.camera.updateProjectionMatrix();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;this.pointMap=h;this.update()}function Ab(a,b){this.object=a;void 0===b&&(b=16776960);var c=new Uint16Array([0,
-1,1,2,2,3,3,0,4,5,5,6,6,7,7,4,0,4,1,5,2,6,3,7]),d=new Float32Array(24),e=new E;e.setIndex(new Z(c,1));e.addAttribute("position",new Z(d,3));Q.call(this,e,new ea({color:b}));this.matrixAutoUpdate=!1;this.update()}function Bb(a,b,c,d,e,f){z.call(this);void 0===d&&(d=16776960);void 0===c&&(c=1);void 0===e&&(e=.2*c);void 0===f&&(f=.2*e);void 0===Kd&&(Kd=new E,Kd.addAttribute("position",new B([0,0,0,0,1,0],3)),qe=new Ua(0,.5,1,5,1),qe.translate(0,-.5,0));this.position.copy(b);this.line=new sa(Kd,new ea({color:d}));
-this.line.matrixAutoUpdate=!1;this.add(this.line);this.cone=new la(qe,new ya({color:d}));this.cone.matrixAutoUpdate=!1;this.add(this.cone);this.setDirection(a);this.setLength(c,e,f)}function Ld(a){a=a||1;var b=[0,0,0,a,0,0,0,0,0,0,a,0,0,0,0,0,0,a];a=new E;a.addAttribute("position",new B(b,3));a.addAttribute("color",new B([1,0,0,1,.6,0,0,1,0,.6,1,0,0,0,1,0,.6,1],3));b=new ea({vertexColors:2});Q.call(this,a,b)}function re(){var a=0,b=0,c=0,d=0;return{initCatmullRom:function(e,f,g,h,k){e=k*(g-e);h=k*
-(h-f);a=f;b=e;c=-3*f+3*g-2*e-h;d=2*f-2*g+e+h},initNonuniformCatmullRom:function(e,f,g,h,k,m,q){e=((f-e)/k-(g-e)/(k+m)+(g-f)/m)*m;h=((g-f)/m-(h-f)/(m+q)+(h-g)/q)*m;a=f;b=e;c=-3*f+3*g-2*e-h;d=2*f-2*g+e+h},calc:function(e){var f=e*e;return a+b*e+c*f+d*f*e}}}function La(a){this.arcLengthDivisions=200;2>a.length&&console.warn("THREE.CatmullRomCurve3: Points array needs at least two entries.");this.points=a||[];this.closed=!1}function bd(a,b,c,d){this.arcLengthDivisions=200;this.v0=a;this.v1=b;this.v2=
-c;this.v3=d}function cd(a,b,c){this.arcLengthDivisions=200;this.v0=a;this.v1=b;this.v2=c}function dd(a,b){this.arcLengthDivisions=200;this.v1=a;this.v2=b}function Md(a,b,c,d,e,f){Va.call(this,a,b,c,c,d,e,f)}function cf(a){console.warn("THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.");La.call(this,a);this.type="catmullrom";this.closed=!0}function df(a){console.warn("THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.");La.call(this,a);this.type=
-"catmullrom"}function se(a){console.warn("THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.");La.call(this,a);this.type="catmullrom"}void 0===Number.EPSILON&&(Number.EPSILON=Math.pow(2,-52));void 0===Number.isInteger&&(Number.isInteger=function(a){return"number"===typeof a&&isFinite(a)&&Math.floor(a)===a});void 0===Math.sign&&(Math.sign=function(a){return 0>a?-1:0<a?1:+a});void 0===Function.prototype.name&&Object.defineProperty(Function.prototype,"name",{get:function(){return this.toString().match(/^\s*function\s*([^\(\s]*)/)[1]}});
-void 0===Object.assign&&function(){Object.assign=function(a){if(void 0===a||null===a)throw new TypeError("Cannot convert undefined or null to object");for(var b=Object(a),c=1;c<arguments.length;c++){var d=arguments[c];if(void 0!==d&&null!==d)for(var e in d)Object.prototype.hasOwnProperty.call(d,e)&&(b[e]=d[e])}return b}}();Object.assign(xa.prototype,{addEventListener:function(a,b){void 0===this._listeners&&(this._listeners={});var c=this._listeners;void 0===c[a]&&(c[a]=[]);-1===c[a].indexOf(b)&&c[a].push(b)},
-hasEventListener:function(a,b){if(void 0===this._listeners)return!1;var c=this._listeners;return void 0!==c[a]&&-1!==c[a].indexOf(b)},removeEventListener:function(a,b){if(void 0!==this._listeners){var c=this._listeners[a];if(void 0!==c){var d=c.indexOf(b);-1!==d&&c.splice(d,1)}}},dispatchEvent:function(a){if(void 0!==this._listeners){var b=this._listeners[a.type];if(void 0!==b){a.target=this;for(var b=b.slice(0),c=0,d=b.length;c<d;c++)b[c].call(this,a)}}}});var Y={DEG2RAD:Math.PI/180,RAD2DEG:180/
-Math.PI,generateUUID:function(){var a="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),b=Array(36),c=0,d;return function(){for(var e=0;36>e;e++)8===e||13===e||18===e||23===e?b[e]="-":14===e?b[e]="4":(2>=c&&(c=33554432+16777216*Math.random()|0),d=c&15,c>>=4,b[e]=a[19===e?d&3|8:d]);return b.join("")}}(),clamp:function(a,b,c){return Math.max(b,Math.min(c,a))},euclideanModulo:function(a,b){return(a%b+b)%b},mapLinear:function(a,b,c,d,e){return d+(a-b)*(e-d)/(c-b)},lerp:function(a,
-b,c){return(1-c)*a+c*b},smoothstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*(3-2*a)},smootherstep:function(a,b,c){if(a<=b)return 0;if(a>=c)return 1;a=(a-b)/(c-b);return a*a*a*(a*(6*a-15)+10)},randInt:function(a,b){return a+Math.floor(Math.random()*(b-a+1))},randFloat:function(a,b){return a+Math.random()*(b-a)},randFloatSpread:function(a){return a*(.5-Math.random())},degToRad:function(a){return a*Y.DEG2RAD},radToDeg:function(a){return a*Y.RAD2DEG},isPowerOfTwo:function(a){return 0===
-(a&a-1)&&0!==a},nearestPowerOfTwo:function(a){return Math.pow(2,Math.round(Math.log(a)/Math.LN2))},nextPowerOfTwo:function(a){a--;a|=a>>1;a|=a>>2;a|=a>>4;a|=a>>8;a|=a>>16;a++;return a}};Object.defineProperties(C.prototype,{width:{get:function(){return this.x},set:function(a){this.x=a}},height:{get:function(){return this.y},set:function(a){this.y=a}}});Object.assign(C.prototype,{isVector2:!0,set:function(a,b){this.x=a;this.y=b;return this},setScalar:function(a){this.y=this.x=a;return this},setX:function(a){this.x=
-a;return this},setY:function(a){this.y=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y)},copy:function(a){this.x=a.x;this.y=a.y;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector2: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),
-this.addVectors(a,b);this.x+=a.x;this.y+=a.y;return this},addScalar:function(a){this.x+=a;this.y+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector2: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;return this},subScalar:function(a){this.x-=a;this.y-=a;return this},
-subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;return this},multiply:function(a){this.x*=a.x;this.y*=a.y;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;return this},divide:function(a){this.x/=a.x;this.y/=a.y;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);return this},clamp:function(a,b){this.x=Math.max(a.x,
-Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));return this},clampScalar:function(){var a=new C,b=new C;return function(c,d){a.set(c,c);b.set(d,d);return this.clamp(a,b)}}(),clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this},round:function(){this.x=Math.round(this.x);
-this.y=Math.round(this.y);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);return this},negate:function(){this.x=-this.x;this.y=-this.y;return this},dot:function(a){return this.x*a.x+this.y*a.y},lengthSq:function(){return this.x*this.x+this.y*this.y},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)},normalize:function(){return this.divideScalar(this.length()||
-1)},angle:function(){var a=Math.atan2(this.y,this.x);0>a&&(a+=2*Math.PI);return a},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x;a=this.y-a.y;return b*b+a*a},distanceToManhattan:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)},setLength:function(a){return this.normalize().multiplyScalar(a)},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,
-a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector2: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);return this},rotateAround:function(a,b){var c=Math.cos(b),d=Math.sin(b),e=this.x-
-a.x,f=this.y-a.y;this.x=e*c-f*d+a.x;this.y=e*d+f*c+a.y;return this}});var hf=0;ba.DEFAULT_IMAGE=void 0;ba.DEFAULT_MAPPING=300;Object.defineProperty(ba.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.assign(ba.prototype,xa.prototype,{constructor:ba,isTexture:!0,clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.name=a.name;this.image=a.image;this.mipmaps=a.mipmaps.slice(0);this.mapping=a.mapping;this.wrapS=a.wrapS;this.wrapT=a.wrapT;this.magFilter=
-a.magFilter;this.minFilter=a.minFilter;this.anisotropy=a.anisotropy;this.format=a.format;this.type=a.type;this.offset.copy(a.offset);this.repeat.copy(a.repeat);this.generateMipmaps=a.generateMipmaps;this.premultiplyAlpha=a.premultiplyAlpha;this.flipY=a.flipY;this.unpackAlignment=a.unpackAlignment;this.encoding=a.encoding;return this},toJSON:function(a){if(void 0!==a.textures[this.uuid])return a.textures[this.uuid];var b={metadata:{version:4.5,type:"Texture",generator:"Texture.toJSON"},uuid:this.uuid,
-name:this.name,mapping:this.mapping,repeat:[this.repeat.x,this.repeat.y],offset:[this.offset.x,this.offset.y],wrap:[this.wrapS,this.wrapT],minFilter:this.minFilter,magFilter:this.magFilter,anisotropy:this.anisotropy,flipY:this.flipY};if(void 0!==this.image){var c=this.image;void 0===c.uuid&&(c.uuid=Y.generateUUID());if(void 0===a.images[c.uuid]){var d=a.images,e=c.uuid,f=c.uuid,g;void 0!==c.toDataURL?g=c:(g=document.createElementNS("http://www.w3.org/1999/xhtml","canvas"),g.width=c.width,g.height=
-c.height,g.getContext("2d").drawImage(c,0,0,c.width,c.height));g=2048<g.width||2048<g.height?g.toDataURL("image/jpeg",.6):g.toDataURL("image/png");d[e]={uuid:f,url:g}}b.image=c.uuid}return a.textures[this.uuid]=b},dispose:function(){this.dispatchEvent({type:"dispose"})},transformUv:function(a){if(300===this.mapping){a.multiply(this.repeat);a.add(this.offset);if(0>a.x||1<a.x)switch(this.wrapS){case 1E3:a.x-=Math.floor(a.x);break;case 1001:a.x=0>a.x?0:1;break;case 1002:a.x=1===Math.abs(Math.floor(a.x)%
-2)?Math.ceil(a.x)-a.x:a.x-Math.floor(a.x)}if(0>a.y||1<a.y)switch(this.wrapT){case 1E3:a.y-=Math.floor(a.y);break;case 1001:a.y=0>a.y?0:1;break;case 1002:a.y=1===Math.abs(Math.floor(a.y)%2)?Math.ceil(a.y)-a.y:a.y-Math.floor(a.y)}this.flipY&&(a.y=1-a.y)}}});Object.assign(fa.prototype,{isVector4:!0,set:function(a,b,c,d){this.x=a;this.y=b;this.z=c;this.w=d;return this},setScalar:function(a){this.w=this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},
-setZ:function(a){this.z=a;return this},setW:function(a){this.w=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=b;break;case 1:this.y=b;break;case 2:this.z=b;break;case 3:this.w=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y,this.z,
-this.w)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;this.w=void 0!==a.w?a.w:1;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;this.w+=a.w;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;this.w+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;this.w=a.w+b.w;return this},addScaledVector:function(a,
-b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;this.w+=a.w*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector4: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;this.w-=a.w;return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;this.w-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;this.w=a.w-b.w;return this},multiplyScalar:function(a){this.x*=
-a;this.y*=a;this.z*=a;this.w*=a;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z,e=this.w;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d+a[12]*e;this.y=a[1]*b+a[5]*c+a[9]*d+a[13]*e;this.z=a[2]*b+a[6]*c+a[10]*d+a[14]*e;this.w=a[3]*b+a[7]*c+a[11]*d+a[15]*e;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},setAxisAngleFromQuaternion:function(a){this.w=2*Math.acos(a.w);var b=Math.sqrt(1-a.w*a.w);1E-4>b?(this.x=1,this.z=this.y=0):(this.x=a.x/b,this.y=a.y/b,this.z=a.z/
-b);return this},setAxisAngleFromRotationMatrix:function(a){var b,c,d;a=a.elements;var e=a[0];d=a[4];var f=a[8],g=a[1],h=a[5],k=a[9];c=a[2];b=a[6];var m=a[10];if(.01>Math.abs(d-g)&&.01>Math.abs(f-c)&&.01>Math.abs(k-b)){if(.1>Math.abs(d+g)&&.1>Math.abs(f+c)&&.1>Math.abs(k+b)&&.1>Math.abs(e+h+m-3))return this.set(1,0,0,0),this;a=Math.PI;e=(e+1)/2;h=(h+1)/2;m=(m+1)/2;d=(d+g)/4;f=(f+c)/4;k=(k+b)/4;e>h&&e>m?.01>e?(b=0,d=c=.707106781):(b=Math.sqrt(e),c=d/b,d=f/b):h>m?.01>h?(b=.707106781,c=0,d=.707106781):
-(c=Math.sqrt(h),b=d/c,d=k/c):.01>m?(c=b=.707106781,d=0):(d=Math.sqrt(m),b=f/d,c=k/d);this.set(b,c,d,a);return this}a=Math.sqrt((b-k)*(b-k)+(f-c)*(f-c)+(g-d)*(g-d));.001>Math.abs(a)&&(a=1);this.x=(b-k)/a;this.y=(f-c)/a;this.z=(g-d)/a;this.w=Math.acos((e+h+m-1)/2);return this},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);this.w=Math.min(this.w,a.w);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,
-a.z);this.w=Math.max(this.w,a.w);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));this.w=Math.max(a.w,Math.min(b.w,this.w));return this},clampScalar:function(){var a,b;return function(c,d){void 0===a&&(a=new fa,b=new fa);a.set(c,c,c,c);b.set(d,d,d,d);return this.clamp(a,b)}}(),clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,
-c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);this.w=Math.floor(this.w);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);this.w=Math.ceil(this.w);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);this.z=Math.round(this.z);this.w=Math.round(this.w);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):
-Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);this.w=0>this.w?Math.ceil(this.w):Math.floor(this.w);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;this.w=-this.w;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z+this.w*a.w},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},lengthManhattan:function(){return Math.abs(this.x)+
-Math.abs(this.y)+Math.abs(this.z)+Math.abs(this.w)},normalize:function(){return this.divideScalar(this.length()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;this.w+=(a.w-this.w)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z&&a.w===this.w},fromArray:function(a,b){void 0===
-b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];this.w=a[b+3];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;a[b+3]=this.w;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector4: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);this.w=a.getW(b);return this}});Object.assign(Cb.prototype,xa.prototype,{isWebGLRenderTarget:!0,setSize:function(a,b){if(this.width!==
-a||this.height!==b)this.width=a,this.height=b,this.dispose();this.viewport.set(0,0,a,b);this.scissor.set(0,0,a,b)},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.width=a.width;this.height=a.height;this.viewport.copy(a.viewport);this.texture=a.texture.clone();this.depthBuffer=a.depthBuffer;this.stencilBuffer=a.stencilBuffer;this.depthTexture=a.depthTexture;return this},dispose:function(){this.dispatchEvent({type:"dispose"})}});Db.prototype=Object.create(Cb.prototype);
-Db.prototype.constructor=Db;Db.prototype.isWebGLRenderTargetCube=!0;Object.assign(oa,{slerp:function(a,b,c,d){return c.copy(a).slerp(b,d)},slerpFlat:function(a,b,c,d,e,f,g){var h=c[d+0],k=c[d+1],m=c[d+2];c=c[d+3];d=e[f+0];var q=e[f+1],l=e[f+2];e=e[f+3];if(c!==e||h!==d||k!==q||m!==l){f=1-g;var p=h*d+k*q+m*l+c*e,r=0<=p?1:-1,n=1-p*p;n>Number.EPSILON&&(n=Math.sqrt(n),p=Math.atan2(n,p*r),f=Math.sin(f*p)/n,g=Math.sin(g*p)/n);r*=g;h=h*f+d*r;k=k*f+q*r;m=m*f+l*r;c=c*f+e*r;f===1-g&&(g=1/Math.sqrt(h*h+k*k+m*
-m+c*c),h*=g,k*=g,m*=g,c*=g)}a[b]=h;a[b+1]=k;a[b+2]=m;a[b+3]=c}});Object.defineProperties(oa.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this.onChangeCallback()}},y:{get:function(){return this._y},set:function(a){this._y=a;this.onChangeCallback()}},z:{get:function(){return this._z},set:function(a){this._z=a;this.onChangeCallback()}},w:{get:function(){return this._w},set:function(a){this._w=a;this.onChangeCallback()}}});Object.assign(oa.prototype,{set:function(a,b,c,d){this._x=
-a;this._y=b;this._z=c;this._w=d;this.onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._w)},copy:function(a){this._x=a.x;this._y=a.y;this._z=a.z;this._w=a.w;this.onChangeCallback();return this},setFromEuler:function(a,b){if(!a||!a.isEuler)throw Error("THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.");var c=a._x,d=a._y,e=a._z,f=a.order,g=Math.cos,h=Math.sin,k=g(c/2),m=g(d/2),g=g(e/2),c=h(c/2),d=
-h(d/2),e=h(e/2);"XYZ"===f?(this._x=c*m*g+k*d*e,this._y=k*d*g-c*m*e,this._z=k*m*e+c*d*g,this._w=k*m*g-c*d*e):"YXZ"===f?(this._x=c*m*g+k*d*e,this._y=k*d*g-c*m*e,this._z=k*m*e-c*d*g,this._w=k*m*g+c*d*e):"ZXY"===f?(this._x=c*m*g-k*d*e,this._y=k*d*g+c*m*e,this._z=k*m*e+c*d*g,this._w=k*m*g-c*d*e):"ZYX"===f?(this._x=c*m*g-k*d*e,this._y=k*d*g+c*m*e,this._z=k*m*e-c*d*g,this._w=k*m*g+c*d*e):"YZX"===f?(this._x=c*m*g+k*d*e,this._y=k*d*g+c*m*e,this._z=k*m*e-c*d*g,this._w=k*m*g-c*d*e):"XZY"===f&&(this._x=c*m*g-
-k*d*e,this._y=k*d*g-c*m*e,this._z=k*m*e+c*d*g,this._w=k*m*g+c*d*e);if(!1!==b)this.onChangeCallback();return this},setFromAxisAngle:function(a,b){var c=b/2,d=Math.sin(c);this._x=a.x*d;this._y=a.y*d;this._z=a.z*d;this._w=Math.cos(c);this.onChangeCallback();return this},setFromRotationMatrix:function(a){var b=a.elements,c=b[0];a=b[4];var d=b[8],e=b[1],f=b[5],g=b[9],h=b[2],k=b[6],b=b[10],m=c+f+b;0<m?(c=.5/Math.sqrt(m+1),this._w=.25/c,this._x=(k-g)*c,this._y=(d-h)*c,this._z=(e-a)*c):c>f&&c>b?(c=2*Math.sqrt(1+
-c-f-b),this._w=(k-g)/c,this._x=.25*c,this._y=(a+e)/c,this._z=(d+h)/c):f>b?(c=2*Math.sqrt(1+f-c-b),this._w=(d-h)/c,this._x=(a+e)/c,this._y=.25*c,this._z=(g+k)/c):(c=2*Math.sqrt(1+b-c-f),this._w=(e-a)/c,this._x=(d+h)/c,this._y=(g+k)/c,this._z=.25*c);this.onChangeCallback();return this},setFromUnitVectors:function(){var a=new n,b;return function(c,d){void 0===a&&(a=new n);b=c.dot(d)+1;1E-6>b?(b=0,Math.abs(c.x)>Math.abs(c.z)?a.set(-c.y,c.x,0):a.set(0,-c.z,c.y)):a.crossVectors(c,d);this._x=a.x;this._y=
-a.y;this._z=a.z;this._w=b;return this.normalize()}}(),inverse:function(){return this.conjugate().normalize()},conjugate:function(){this._x*=-1;this._y*=-1;this._z*=-1;this.onChangeCallback();return this},dot:function(a){return this._x*a._x+this._y*a._y+this._z*a._z+this._w*a._w},lengthSq:function(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w},length:function(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)},normalize:function(){var a=this.length();
-0===a?(this._z=this._y=this._x=0,this._w=1):(a=1/a,this._x*=a,this._y*=a,this._z*=a,this._w*=a);this.onChangeCallback();return this},multiply:function(a,b){return void 0!==b?(console.warn("THREE.Quaternion: .multiply() now only accepts one argument. Use .multiplyQuaternions( a, b ) instead."),this.multiplyQuaternions(a,b)):this.multiplyQuaternions(this,a)},premultiply:function(a){return this.multiplyQuaternions(a,this)},multiplyQuaternions:function(a,b){var c=a._x,d=a._y,e=a._z,f=a._w,g=b._x,h=b._y,
-k=b._z,m=b._w;this._x=c*m+f*g+d*k-e*h;this._y=d*m+f*h+e*g-c*k;this._z=e*m+f*k+c*h-d*g;this._w=f*m-c*g-d*h-e*k;this.onChangeCallback();return this},slerp:function(a,b){if(0===b)return this;if(1===b)return this.copy(a);var c=this._x,d=this._y,e=this._z,f=this._w,g=f*a._w+c*a._x+d*a._y+e*a._z;0>g?(this._w=-a._w,this._x=-a._x,this._y=-a._y,this._z=-a._z,g=-g):this.copy(a);if(1<=g)return this._w=f,this._x=c,this._y=d,this._z=e,this;var h=Math.sqrt(1-g*g);if(.001>Math.abs(h))return this._w=.5*(f+this._w),
-this._x=.5*(c+this._x),this._y=.5*(d+this._y),this._z=.5*(e+this._z),this;var k=Math.atan2(h,g),g=Math.sin((1-b)*k)/h,h=Math.sin(b*k)/h;this._w=f*g+this._w*h;this._x=c*g+this._x*h;this._y=d*g+this._y*h;this._z=e*g+this._z*h;this.onChangeCallback();return this},equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._w===this._w},fromArray:function(a,b){void 0===b&&(b=0);this._x=a[b];this._y=a[b+1];this._z=a[b+2];this._w=a[b+3];this.onChangeCallback();return this},toArray:function(a,
-b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._w;return a},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){}});Object.assign(n.prototype,{isVector3:!0,set:function(a,b,c){this.x=a;this.y=b;this.z=c;return this},setScalar:function(a){this.z=this.y=this.x=a;return this},setX:function(a){this.x=a;return this},setY:function(a){this.y=a;return this},setZ:function(a){this.z=a;return this},setComponent:function(a,b){switch(a){case 0:this.x=
-b;break;case 1:this.y=b;break;case 2:this.z=b;break;default:throw Error("index is out of range: "+a);}return this},getComponent:function(a){switch(a){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw Error("index is out of range: "+a);}},clone:function(){return new this.constructor(this.x,this.y,this.z)},copy:function(a){this.x=a.x;this.y=a.y;this.z=a.z;return this},add:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .add() now only accepts one argument. Use .addVectors( a, b ) instead."),
-this.addVectors(a,b);this.x+=a.x;this.y+=a.y;this.z+=a.z;return this},addScalar:function(a){this.x+=a;this.y+=a;this.z+=a;return this},addVectors:function(a,b){this.x=a.x+b.x;this.y=a.y+b.y;this.z=a.z+b.z;return this},addScaledVector:function(a,b){this.x+=a.x*b;this.y+=a.y*b;this.z+=a.z*b;return this},sub:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .sub() now only accepts one argument. Use .subVectors( a, b ) instead."),this.subVectors(a,b);this.x-=a.x;this.y-=a.y;this.z-=a.z;
-return this},subScalar:function(a){this.x-=a;this.y-=a;this.z-=a;return this},subVectors:function(a,b){this.x=a.x-b.x;this.y=a.y-b.y;this.z=a.z-b.z;return this},multiply:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .multiply() now only accepts one argument. Use .multiplyVectors( a, b ) instead."),this.multiplyVectors(a,b);this.x*=a.x;this.y*=a.y;this.z*=a.z;return this},multiplyScalar:function(a){this.x*=a;this.y*=a;this.z*=a;return this},multiplyVectors:function(a,b){this.x=a.x*
-b.x;this.y=a.y*b.y;this.z=a.z*b.z;return this},applyEuler:function(){var a=new oa;return function(b){b&&b.isEuler||console.error("THREE.Vector3: .applyEuler() now expects an Euler rotation rather than a Vector3 and order.");return this.applyQuaternion(a.setFromEuler(b))}}(),applyAxisAngle:function(){var a=new oa;return function(b,c){return this.applyQuaternion(a.setFromAxisAngle(b,c))}}(),applyMatrix3:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[3]*c+a[6]*d;this.y=a[1]*
-b+a[4]*c+a[7]*d;this.z=a[2]*b+a[5]*c+a[8]*d;return this},applyMatrix4:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;var e=1/(a[3]*b+a[7]*c+a[11]*d+a[15]);this.x=(a[0]*b+a[4]*c+a[8]*d+a[12])*e;this.y=(a[1]*b+a[5]*c+a[9]*d+a[13])*e;this.z=(a[2]*b+a[6]*c+a[10]*d+a[14])*e;return this},applyQuaternion:function(a){var b=this.x,c=this.y,d=this.z,e=a.x,f=a.y,g=a.z;a=a.w;var h=a*b+f*d-g*c,k=a*c+g*b-e*d,m=a*d+e*c-f*b,b=-e*b-f*c-g*d;this.x=h*a+b*-e+k*-g-m*-f;this.y=k*a+b*-f+m*-e-h*-g;this.z=m*a+b*
--g+h*-f-k*-e;return this},project:function(){var a=new K;return function(b){a.multiplyMatrices(b.projectionMatrix,a.getInverse(b.matrixWorld));return this.applyMatrix4(a)}}(),unproject:function(){var a=new K;return function(b){a.multiplyMatrices(b.matrixWorld,a.getInverse(b.projectionMatrix));return this.applyMatrix4(a)}}(),transformDirection:function(a){var b=this.x,c=this.y,d=this.z;a=a.elements;this.x=a[0]*b+a[4]*c+a[8]*d;this.y=a[1]*b+a[5]*c+a[9]*d;this.z=a[2]*b+a[6]*c+a[10]*d;return this.normalize()},
-divide:function(a){this.x/=a.x;this.y/=a.y;this.z/=a.z;return this},divideScalar:function(a){return this.multiplyScalar(1/a)},min:function(a){this.x=Math.min(this.x,a.x);this.y=Math.min(this.y,a.y);this.z=Math.min(this.z,a.z);return this},max:function(a){this.x=Math.max(this.x,a.x);this.y=Math.max(this.y,a.y);this.z=Math.max(this.z,a.z);return this},clamp:function(a,b){this.x=Math.max(a.x,Math.min(b.x,this.x));this.y=Math.max(a.y,Math.min(b.y,this.y));this.z=Math.max(a.z,Math.min(b.z,this.z));return this},
-clampScalar:function(){var a=new n,b=new n;return function(c,d){a.set(c,c,c);b.set(d,d,d);return this.clamp(a,b)}}(),clampLength:function(a,b){var c=this.length();return this.divideScalar(c||1).multiplyScalar(Math.max(a,Math.min(b,c)))},floor:function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);this.z=Math.floor(this.z);return this},ceil:function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);this.z=Math.ceil(this.z);return this},round:function(){this.x=Math.round(this.x);this.y=Math.round(this.y);
-this.z=Math.round(this.z);return this},roundToZero:function(){this.x=0>this.x?Math.ceil(this.x):Math.floor(this.x);this.y=0>this.y?Math.ceil(this.y):Math.floor(this.y);this.z=0>this.z?Math.ceil(this.z):Math.floor(this.z);return this},negate:function(){this.x=-this.x;this.y=-this.y;this.z=-this.z;return this},dot:function(a){return this.x*a.x+this.y*a.y+this.z*a.z},lengthSq:function(){return this.x*this.x+this.y*this.y+this.z*this.z},length:function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*
-this.z)},lengthManhattan:function(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)},normalize:function(){return this.divideScalar(this.length()||1)},setLength:function(a){return this.normalize().multiplyScalar(a)},lerp:function(a,b){this.x+=(a.x-this.x)*b;this.y+=(a.y-this.y)*b;this.z+=(a.z-this.z)*b;return this},lerpVectors:function(a,b,c){return this.subVectors(b,a).multiplyScalar(c).add(a)},cross:function(a,b){if(void 0!==b)return console.warn("THREE.Vector3: .cross() now only accepts one argument. Use .crossVectors( a, b ) instead."),
-this.crossVectors(a,b);var c=this.x,d=this.y,e=this.z;this.x=d*a.z-e*a.y;this.y=e*a.x-c*a.z;this.z=c*a.y-d*a.x;return this},crossVectors:function(a,b){var c=a.x,d=a.y,e=a.z,f=b.x,g=b.y,h=b.z;this.x=d*h-e*g;this.y=e*f-c*h;this.z=c*g-d*f;return this},projectOnVector:function(a){var b=a.dot(this)/a.lengthSq();return this.copy(a).multiplyScalar(b)},projectOnPlane:function(){var a=new n;return function(b){a.copy(this).projectOnVector(b);return this.sub(a)}}(),reflect:function(){var a=new n;return function(b){return this.sub(a.copy(b).multiplyScalar(2*
-this.dot(b)))}}(),angleTo:function(a){a=this.dot(a)/Math.sqrt(this.lengthSq()*a.lengthSq());return Math.acos(Y.clamp(a,-1,1))},distanceTo:function(a){return Math.sqrt(this.distanceToSquared(a))},distanceToSquared:function(a){var b=this.x-a.x,c=this.y-a.y;a=this.z-a.z;return b*b+c*c+a*a},distanceToManhattan:function(a){return Math.abs(this.x-a.x)+Math.abs(this.y-a.y)+Math.abs(this.z-a.z)},setFromSpherical:function(a){var b=Math.sin(a.phi)*a.radius;this.x=b*Math.sin(a.theta);this.y=Math.cos(a.phi)*
-a.radius;this.z=b*Math.cos(a.theta);return this},setFromCylindrical:function(a){this.x=a.radius*Math.sin(a.theta);this.y=a.y;this.z=a.radius*Math.cos(a.theta);return this},setFromMatrixPosition:function(a){a=a.elements;this.x=a[12];this.y=a[13];this.z=a[14];return this},setFromMatrixScale:function(a){var b=this.setFromMatrixColumn(a,0).length(),c=this.setFromMatrixColumn(a,1).length();a=this.setFromMatrixColumn(a,2).length();this.x=b;this.y=c;this.z=a;return this},setFromMatrixColumn:function(a,b){return this.fromArray(a.elements,
-4*b)},equals:function(a){return a.x===this.x&&a.y===this.y&&a.z===this.z},fromArray:function(a,b){void 0===b&&(b=0);this.x=a[b];this.y=a[b+1];this.z=a[b+2];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.x;a[b+1]=this.y;a[b+2]=this.z;return a},fromBufferAttribute:function(a,b,c){void 0!==c&&console.warn("THREE.Vector3: offset has been removed from .fromBufferAttribute().");this.x=a.getX(b);this.y=a.getY(b);this.z=a.getZ(b);return this}});Object.assign(K.prototype,
-{isMatrix4:!0,set:function(a,b,c,d,e,f,g,h,k,m,q,l,p,r,n,t){var y=this.elements;y[0]=a;y[4]=b;y[8]=c;y[12]=d;y[1]=e;y[5]=f;y[9]=g;y[13]=h;y[2]=k;y[6]=m;y[10]=q;y[14]=l;y[3]=p;y[7]=r;y[11]=n;y[15]=t;return this},identity:function(){this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);return this},clone:function(){return(new K).fromArray(this.elements)},copy:function(a){var b=this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];b[9]=a[9];b[10]=a[10];
-b[11]=a[11];b[12]=a[12];b[13]=a[13];b[14]=a[14];b[15]=a[15];return this},copyPosition:function(a){var b=this.elements;a=a.elements;b[12]=a[12];b[13]=a[13];b[14]=a[14];return this},extractBasis:function(a,b,c){a.setFromMatrixColumn(this,0);b.setFromMatrixColumn(this,1);c.setFromMatrixColumn(this,2);return this},makeBasis:function(a,b,c){this.set(a.x,b.x,c.x,0,a.y,b.y,c.y,0,a.z,b.z,c.z,0,0,0,0,1);return this},extractRotation:function(){var a=new n;return function(b){var c=this.elements,d=b.elements,
-e=1/a.setFromMatrixColumn(b,0).length(),f=1/a.setFromMatrixColumn(b,1).length();b=1/a.setFromMatrixColumn(b,2).length();c[0]=d[0]*e;c[1]=d[1]*e;c[2]=d[2]*e;c[4]=d[4]*f;c[5]=d[5]*f;c[6]=d[6]*f;c[8]=d[8]*b;c[9]=d[9]*b;c[10]=d[10]*b;return this}}(),makeRotationFromEuler:function(a){a&&a.isEuler||console.error("THREE.Matrix: .makeRotationFromEuler() now expects a Euler rotation rather than a Vector3 and order.");var b=this.elements,c=a.x,d=a.y,e=a.z,f=Math.cos(c),c=Math.sin(c),g=Math.cos(d),d=Math.sin(d),
-h=Math.cos(e),e=Math.sin(e);if("XYZ"===a.order){a=f*h;var k=f*e,m=c*h,q=c*e;b[0]=g*h;b[4]=-g*e;b[8]=d;b[1]=k+m*d;b[5]=a-q*d;b[9]=-c*g;b[2]=q-a*d;b[6]=m+k*d;b[10]=f*g}else"YXZ"===a.order?(a=g*h,k=g*e,m=d*h,q=d*e,b[0]=a+q*c,b[4]=m*c-k,b[8]=f*d,b[1]=f*e,b[5]=f*h,b[9]=-c,b[2]=k*c-m,b[6]=q+a*c,b[10]=f*g):"ZXY"===a.order?(a=g*h,k=g*e,m=d*h,q=d*e,b[0]=a-q*c,b[4]=-f*e,b[8]=m+k*c,b[1]=k+m*c,b[5]=f*h,b[9]=q-a*c,b[2]=-f*d,b[6]=c,b[10]=f*g):"ZYX"===a.order?(a=f*h,k=f*e,m=c*h,q=c*e,b[0]=g*h,b[4]=m*d-k,b[8]=a*
-d+q,b[1]=g*e,b[5]=q*d+a,b[9]=k*d-m,b[2]=-d,b[6]=c*g,b[10]=f*g):"YZX"===a.order?(a=f*g,k=f*d,m=c*g,q=c*d,b[0]=g*h,b[4]=q-a*e,b[8]=m*e+k,b[1]=e,b[5]=f*h,b[9]=-c*h,b[2]=-d*h,b[6]=k*e+m,b[10]=a-q*e):"XZY"===a.order&&(a=f*g,k=f*d,m=c*g,q=c*d,b[0]=g*h,b[4]=-e,b[8]=d*h,b[1]=a*e+q,b[5]=f*h,b[9]=k*e-m,b[2]=m*e-k,b[6]=c*h,b[10]=q*e+a);b[3]=0;b[7]=0;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},makeRotationFromQuaternion:function(a){var b=this.elements,c=a._x,d=a._y,e=a._z,f=a._w,g=c+c,h=d+d,k=e+e;a=
-c*g;var m=c*h,c=c*k,q=d*h,d=d*k,e=e*k,g=f*g,h=f*h,f=f*k;b[0]=1-(q+e);b[4]=m-f;b[8]=c+h;b[1]=m+f;b[5]=1-(a+e);b[9]=d-g;b[2]=c-h;b[6]=d+g;b[10]=1-(a+q);b[3]=0;b[7]=0;b[11]=0;b[12]=0;b[13]=0;b[14]=0;b[15]=1;return this},lookAt:function(){var a=new n,b=new n,c=new n;return function(d,e,f){var g=this.elements;c.subVectors(d,e);0===c.lengthSq()&&(c.z=1);c.normalize();a.crossVectors(f,c);0===a.lengthSq()&&(1===Math.abs(f.z)?c.x+=1E-4:c.z+=1E-4,c.normalize(),a.crossVectors(f,c));a.normalize();b.crossVectors(c,
-a);g[0]=a.x;g[4]=b.x;g[8]=c.x;g[1]=a.y;g[5]=b.y;g[9]=c.y;g[2]=a.z;g[6]=b.z;g[10]=c.z;return this}}(),multiply:function(a,b){return void 0!==b?(console.warn("THREE.Matrix4: .multiply() now only accepts one argument. Use .multiplyMatrices( a, b ) instead."),this.multiplyMatrices(a,b)):this.multiplyMatrices(this,a)},premultiply:function(a){return this.multiplyMatrices(a,this)},multiplyMatrices:function(a,b){var c=a.elements,d=b.elements,e=this.elements,f=c[0],g=c[4],h=c[8],k=c[12],m=c[1],q=c[5],l=c[9],
-p=c[13],r=c[2],n=c[6],t=c[10],y=c[14],x=c[3],u=c[7],H=c[11],c=c[15],w=d[0],I=d[4],W=d[8],D=d[12],O=d[1],B=d[5],F=d[9],C=d[13],z=d[2],E=d[6],G=d[10],K=d[14],P=d[3],M=d[7],V=d[11],d=d[15];e[0]=f*w+g*O+h*z+k*P;e[4]=f*I+g*B+h*E+k*M;e[8]=f*W+g*F+h*G+k*V;e[12]=f*D+g*C+h*K+k*d;e[1]=m*w+q*O+l*z+p*P;e[5]=m*I+q*B+l*E+p*M;e[9]=m*W+q*F+l*G+p*V;e[13]=m*D+q*C+l*K+p*d;e[2]=r*w+n*O+t*z+y*P;e[6]=r*I+n*B+t*E+y*M;e[10]=r*W+n*F+t*G+y*V;e[14]=r*D+n*C+t*K+y*d;e[3]=x*w+u*O+H*z+c*P;e[7]=x*I+u*B+H*E+c*M;e[11]=x*W+u*F+H*G+
-c*V;e[15]=x*D+u*C+H*K+c*d;return this},multiplyScalar:function(a){var b=this.elements;b[0]*=a;b[4]*=a;b[8]*=a;b[12]*=a;b[1]*=a;b[5]*=a;b[9]*=a;b[13]*=a;b[2]*=a;b[6]*=a;b[10]*=a;b[14]*=a;b[3]*=a;b[7]*=a;b[11]*=a;b[15]*=a;return this},applyToBufferAttribute:function(){var a=new n;return function(b){for(var c=0,d=b.count;c<d;c++)a.x=b.getX(c),a.y=b.getY(c),a.z=b.getZ(c),a.applyMatrix4(this),b.setXYZ(c,a.x,a.y,a.z);return b}}(),determinant:function(){var a=this.elements,b=a[0],c=a[4],d=a[8],e=a[12],f=
-a[1],g=a[5],h=a[9],k=a[13],m=a[2],q=a[6],l=a[10],p=a[14];return a[3]*(+e*h*q-d*k*q-e*g*l+c*k*l+d*g*p-c*h*p)+a[7]*(+b*h*p-b*k*l+e*f*l-d*f*p+d*k*m-e*h*m)+a[11]*(+b*k*q-b*g*p-e*f*q+c*f*p+e*g*m-c*k*m)+a[15]*(-d*g*m-b*h*q+b*g*l+d*f*q-c*f*l+c*h*m)},transpose:function(){var a=this.elements,b;b=a[1];a[1]=a[4];a[4]=b;b=a[2];a[2]=a[8];a[8]=b;b=a[6];a[6]=a[9];a[9]=b;b=a[3];a[3]=a[12];a[12]=b;b=a[7];a[7]=a[13];a[13]=b;b=a[11];a[11]=a[14];a[14]=b;return this},setPosition:function(a){var b=this.elements;b[12]=
-a.x;b[13]=a.y;b[14]=a.z;return this},getInverse:function(a,b){var c=this.elements,d=a.elements,e=d[0],f=d[1],g=d[2],h=d[3],k=d[4],m=d[5],q=d[6],l=d[7],p=d[8],r=d[9],n=d[10],t=d[11],y=d[12],x=d[13],u=d[14],d=d[15],H=r*u*l-x*n*l+x*q*t-m*u*t-r*q*d+m*n*d,w=y*n*l-p*u*l-y*q*t+k*u*t+p*q*d-k*n*d,I=p*x*l-y*r*l+y*m*t-k*x*t-p*m*d+k*r*d,W=y*r*q-p*x*q-y*m*n+k*x*n+p*m*u-k*r*u,D=e*H+f*w+g*I+h*W;if(0===D){if(!0===b)throw Error("THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0");console.warn("THREE.Matrix4.getInverse(): can't invert matrix, determinant is 0");
-return this.identity()}D=1/D;c[0]=H*D;c[1]=(x*n*h-r*u*h-x*g*t+f*u*t+r*g*d-f*n*d)*D;c[2]=(m*u*h-x*q*h+x*g*l-f*u*l-m*g*d+f*q*d)*D;c[3]=(r*q*h-m*n*h-r*g*l+f*n*l+m*g*t-f*q*t)*D;c[4]=w*D;c[5]=(p*u*h-y*n*h+y*g*t-e*u*t-p*g*d+e*n*d)*D;c[6]=(y*q*h-k*u*h-y*g*l+e*u*l+k*g*d-e*q*d)*D;c[7]=(k*n*h-p*q*h+p*g*l-e*n*l-k*g*t+e*q*t)*D;c[8]=I*D;c[9]=(y*r*h-p*x*h-y*f*t+e*x*t+p*f*d-e*r*d)*D;c[10]=(k*x*h-y*m*h+y*f*l-e*x*l-k*f*d+e*m*d)*D;c[11]=(p*m*h-k*r*h-p*f*l+e*r*l+k*f*t-e*m*t)*D;c[12]=W*D;c[13]=(p*x*g-y*r*g+y*f*n-e*x*
-n-p*f*u+e*r*u)*D;c[14]=(y*m*g-k*x*g-y*f*q+e*x*q+k*f*u-e*m*u)*D;c[15]=(k*r*g-p*m*g+p*f*q-e*r*q-k*f*n+e*m*n)*D;return this},scale:function(a){var b=this.elements,c=a.x,d=a.y;a=a.z;b[0]*=c;b[4]*=d;b[8]*=a;b[1]*=c;b[5]*=d;b[9]*=a;b[2]*=c;b[6]*=d;b[10]*=a;b[3]*=c;b[7]*=d;b[11]*=a;return this},getMaxScaleOnAxis:function(){var a=this.elements;return Math.sqrt(Math.max(a[0]*a[0]+a[1]*a[1]+a[2]*a[2],a[4]*a[4]+a[5]*a[5]+a[6]*a[6],a[8]*a[8]+a[9]*a[9]+a[10]*a[10]))},makeTranslation:function(a,b,c){this.set(1,
-0,0,a,0,1,0,b,0,0,1,c,0,0,0,1);return this},makeRotationX:function(a){var b=Math.cos(a);a=Math.sin(a);this.set(1,0,0,0,0,b,-a,0,0,a,b,0,0,0,0,1);return this},makeRotationY:function(a){var b=Math.cos(a);a=Math.sin(a);this.set(b,0,a,0,0,1,0,0,-a,0,b,0,0,0,0,1);return this},makeRotationZ:function(a){var b=Math.cos(a);a=Math.sin(a);this.set(b,-a,0,0,a,b,0,0,0,0,1,0,0,0,0,1);return this},makeRotationAxis:function(a,b){var c=Math.cos(b),d=Math.sin(b),e=1-c,f=a.x,g=a.y,h=a.z,k=e*f,m=e*g;this.set(k*f+c,k*
-g-d*h,k*h+d*g,0,k*g+d*h,m*g+c,m*h-d*f,0,k*h-d*g,m*h+d*f,e*h*h+c,0,0,0,0,1);return this},makeScale:function(a,b,c){this.set(a,0,0,0,0,b,0,0,0,0,c,0,0,0,0,1);return this},makeShear:function(a,b,c){this.set(1,b,c,0,a,1,c,0,a,b,1,0,0,0,0,1);return this},compose:function(a,b,c){this.makeRotationFromQuaternion(b);this.scale(c);this.setPosition(a);return this},decompose:function(){var a=new n,b=new K;return function(c,d,e){var f=this.elements,g=a.set(f[0],f[1],f[2]).length(),h=a.set(f[4],f[5],f[6]).length(),
-k=a.set(f[8],f[9],f[10]).length();0>this.determinant()&&(g=-g);c.x=f[12];c.y=f[13];c.z=f[14];b.copy(this);c=1/g;var f=1/h,m=1/k;b.elements[0]*=c;b.elements[1]*=c;b.elements[2]*=c;b.elements[4]*=f;b.elements[5]*=f;b.elements[6]*=f;b.elements[8]*=m;b.elements[9]*=m;b.elements[10]*=m;d.setFromRotationMatrix(b);e.x=g;e.y=h;e.z=k;return this}}(),makePerspective:function(a,b,c,d,e,f){void 0===f&&console.warn("THREE.Matrix4: .makePerspective() has been redefined and has a new signature. Please check the docs.");
-var g=this.elements;g[0]=2*e/(b-a);g[4]=0;g[8]=(b+a)/(b-a);g[12]=0;g[1]=0;g[5]=2*e/(c-d);g[9]=(c+d)/(c-d);g[13]=0;g[2]=0;g[6]=0;g[10]=-(f+e)/(f-e);g[14]=-2*f*e/(f-e);g[3]=0;g[7]=0;g[11]=-1;g[15]=0;return this},makeOrthographic:function(a,b,c,d,e,f){var g=this.elements,h=1/(b-a),k=1/(c-d),m=1/(f-e);g[0]=2*h;g[4]=0;g[8]=0;g[12]=-((b+a)*h);g[1]=0;g[5]=2*k;g[9]=0;g[13]=-((c+d)*k);g[2]=0;g[6]=0;g[10]=-2*m;g[14]=-((f+e)*m);g[3]=0;g[7]=0;g[11]=0;g[15]=1;return this},equals:function(a){var b=this.elements;
-a=a.elements;for(var c=0;16>c;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;16>c;c++)this.elements[c]=a[c+b];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];a[b+9]=c[9];a[b+10]=c[10];a[b+11]=c[11];a[b+12]=c[12];a[b+13]=c[13];a[b+14]=c[14];a[b+15]=c[15];return a}});db.prototype=Object.create(ba.prototype);
-db.prototype.constructor=db;db.prototype.isDataTexture=!0;Xa.prototype=Object.create(ba.prototype);Xa.prototype.constructor=Xa;Xa.prototype.isCubeTexture=!0;Object.defineProperty(Xa.prototype,"images",{get:function(){return this.image},set:function(a){this.image=a}});var Ce=new ba,De=new Xa,xe=[],ze=[],Be=new Float32Array(16),Ae=new Float32Array(9);He.prototype.setValue=function(a,b){for(var c=this.seq,d=0,e=c.length;d!==e;++d){var f=c[d];f.setValue(a,b[f.id])}};var Pd=/([\w\d_]+)(\])?(\[|\.)?/g;
-eb.prototype.setValue=function(a,b,c){b=this.map[b];void 0!==b&&b.setValue(a,c,this.renderer)};eb.prototype.setOptional=function(a,b,c){b=b[c];void 0!==b&&this.setValue(a,c,b)};eb.upload=function(a,b,c,d){for(var e=0,f=b.length;e!==f;++e){var g=b[e],h=c[g.id];!1!==h.needsUpdate&&g.setValue(a,h.value,d)}};eb.seqWithValue=function(a,b){for(var c=[],d=0,e=a.length;d!==e;++d){var f=a[d];f.id in b&&c.push(f)}return c};var lg={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,
-beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,
-darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,
-khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,
-mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,
-peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,
-yellow:16776960,yellowgreen:10145074};Object.assign(G.prototype,{isColor:!0,r:1,g:1,b:1,set:function(a){a&&a.isColor?this.copy(a):"number"===typeof a?this.setHex(a):"string"===typeof a&&this.setStyle(a);return this},setScalar:function(a){this.b=this.g=this.r=a;return this},setHex:function(a){a=Math.floor(a);this.r=(a>>16&255)/255;this.g=(a>>8&255)/255;this.b=(a&255)/255;return this},setRGB:function(a,b,c){this.r=a;this.g=b;this.b=c;return this},setHSL:function(){function a(a,c,d){0>d&&(d+=1);1<d&&
---d;return d<1/6?a+6*(c-a)*d:.5>d?c:d<2/3?a+6*(c-a)*(2/3-d):a}return function(b,c,d){b=Y.euclideanModulo(b,1);c=Y.clamp(c,0,1);d=Y.clamp(d,0,1);0===c?this.r=this.g=this.b=d:(c=.5>=d?d*(1+c):d+c-d*c,d=2*d-c,this.r=a(d,c,b+1/3),this.g=a(d,c,b),this.b=a(d,c,b-1/3));return this}}(),setStyle:function(a){function b(b){void 0!==b&&1>parseFloat(b)&&console.warn("THREE.Color: Alpha component of "+a+" will be ignored.")}var c;if(c=/^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec(a)){var d=c[2];switch(c[1]){case "rgb":case "rgba":if(c=
-/^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d))return this.r=Math.min(255,parseInt(c[1],10))/255,this.g=Math.min(255,parseInt(c[2],10))/255,this.b=Math.min(255,parseInt(c[3],10))/255,b(c[5]),this;if(c=/^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d))return this.r=Math.min(100,parseInt(c[1],10))/100,this.g=Math.min(100,parseInt(c[2],10))/100,this.b=Math.min(100,parseInt(c[3],10))/100,b(c[5]),this;break;case "hsl":case "hsla":if(c=/^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec(d)){var d=
-parseFloat(c[1])/360,e=parseInt(c[2],10)/100,f=parseInt(c[3],10)/100;b(c[5]);return this.setHSL(d,e,f)}}}else if(c=/^\#([A-Fa-f0-9]+)$/.exec(a)){c=c[1];d=c.length;if(3===d)return this.r=parseInt(c.charAt(0)+c.charAt(0),16)/255,this.g=parseInt(c.charAt(1)+c.charAt(1),16)/255,this.b=parseInt(c.charAt(2)+c.charAt(2),16)/255,this;if(6===d)return this.r=parseInt(c.charAt(0)+c.charAt(1),16)/255,this.g=parseInt(c.charAt(2)+c.charAt(3),16)/255,this.b=parseInt(c.charAt(4)+c.charAt(5),16)/255,this}a&&0<a.length&&
-(c=lg[a],void 0!==c?this.setHex(c):console.warn("THREE.Color: Unknown color "+a));return this},clone:function(){return new this.constructor(this.r,this.g,this.b)},copy:function(a){this.r=a.r;this.g=a.g;this.b=a.b;return this},copyGammaToLinear:function(a,b){void 0===b&&(b=2);this.r=Math.pow(a.r,b);this.g=Math.pow(a.g,b);this.b=Math.pow(a.b,b);return this},copyLinearToGamma:function(a,b){void 0===b&&(b=2);var c=0<b?1/b:1;this.r=Math.pow(a.r,c);this.g=Math.pow(a.g,c);this.b=Math.pow(a.b,c);return this},
-convertGammaToLinear:function(){var a=this.r,b=this.g,c=this.b;this.r=a*a;this.g=b*b;this.b=c*c;return this},convertLinearToGamma:function(){this.r=Math.sqrt(this.r);this.g=Math.sqrt(this.g);this.b=Math.sqrt(this.b);return this},getHex:function(){return 255*this.r<<16^255*this.g<<8^255*this.b<<0},getHexString:function(){return("000000"+this.getHex().toString(16)).slice(-6)},getHSL:function(a){a=a||{h:0,s:0,l:0};var b=this.r,c=this.g,d=this.b,e=Math.max(b,c,d),f=Math.min(b,c,d),g,h=(f+e)/2;if(f===
-e)f=g=0;else{var k=e-f,f=.5>=h?k/(e+f):k/(2-e-f);switch(e){case b:g=(c-d)/k+(c<d?6:0);break;case c:g=(d-b)/k+2;break;case d:g=(b-c)/k+4}g/=6}a.h=g;a.s=f;a.l=h;return a},getStyle:function(){return"rgb("+(255*this.r|0)+","+(255*this.g|0)+","+(255*this.b|0)+")"},offsetHSL:function(a,b,c){var d=this.getHSL();d.h+=a;d.s+=b;d.l+=c;this.setHSL(d.h,d.s,d.l);return this},add:function(a){this.r+=a.r;this.g+=a.g;this.b+=a.b;return this},addColors:function(a,b){this.r=a.r+b.r;this.g=a.g+b.g;this.b=a.b+b.b;return this},
-addScalar:function(a){this.r+=a;this.g+=a;this.b+=a;return this},sub:function(a){this.r=Math.max(0,this.r-a.r);this.g=Math.max(0,this.g-a.g);this.b=Math.max(0,this.b-a.b);return this},multiply:function(a){this.r*=a.r;this.g*=a.g;this.b*=a.b;return this},multiplyScalar:function(a){this.r*=a;this.g*=a;this.b*=a;return this},lerp:function(a,b){this.r+=(a.r-this.r)*b;this.g+=(a.g-this.g)*b;this.b+=(a.b-this.b)*b;return this},equals:function(a){return a.r===this.r&&a.g===this.g&&a.b===this.b},fromArray:function(a,
-b){void 0===b&&(b=0);this.r=a[b];this.g=a[b+1];this.b=a[b+2];return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this.r;a[b+1]=this.g;a[b+2]=this.b;return a},toJSON:function(){return this.getHex()}});var R={common:{diffuse:{value:new G(15658734)},opacity:{value:1},map:{value:null},offsetRepeat:{value:new fa(0,0,1,1)},specularMap:{value:null},alphaMap:{value:null},envMap:{value:null},flipEnvMap:{value:-1},reflectivity:{value:1},refractionRatio:{value:.98}},aomap:{aoMap:{value:null},
-aoMapIntensity:{value:1}},lightmap:{lightMap:{value:null},lightMapIntensity:{value:1}},emissivemap:{emissiveMap:{value:null}},bumpmap:{bumpMap:{value:null},bumpScale:{value:1}},normalmap:{normalMap:{value:null},normalScale:{value:new C(1,1)}},displacementmap:{displacementMap:{value:null},displacementScale:{value:1},displacementBias:{value:0}},roughnessmap:{roughnessMap:{value:null}},metalnessmap:{metalnessMap:{value:null}},gradientmap:{gradientMap:{value:null}},fog:{fogDensity:{value:2.5E-4},fogNear:{value:1},
-fogFar:{value:2E3},fogColor:{value:new G(16777215)}},lights:{ambientLightColor:{value:[]},directionalLights:{value:[],properties:{direction:{},color:{},shadow:{},shadowBias:{},shadowRadius:{},shadowMapSize:{}}},directionalShadowMap:{value:[]},directionalShadowMatrix:{value:[]},spotLights:{value:[],properties:{color:{},position:{},direction:{},distance:{},coneCos:{},penumbraCos:{},decay:{},shadow:{},shadowBias:{},shadowRadius:{},shadowMapSize:{}}},spotShadowMap:{value:[]},spotShadowMatrix:{value:[]},
-pointLights:{value:[],properties:{color:{},position:{},decay:{},distance:{},shadow:{},shadowBias:{},shadowRadius:{},shadowMapSize:{}}},pointShadowMap:{value:[]},pointShadowMatrix:{value:[]},hemisphereLights:{value:[],properties:{direction:{},skyColor:{},groundColor:{}}},rectAreaLights:{value:[],properties:{color:{},position:{},width:{},height:{}}}},points:{diffuse:{value:new G(15658734)},opacity:{value:1},size:{value:1},scale:{value:1},map:{value:null},offsetRepeat:{value:new fa(0,0,1,1)}}},Ca={merge:function(a){for(var b=
-{},c=0;c<a.length;c++){var d=this.clone(a[c]),e;for(e in d)b[e]=d[e]}return b},clone:function(a){var b={},c;for(c in a){b[c]={};for(var d in a[c]){var e=a[c][d];e&&(e.isColor||e.isMatrix3||e.isMatrix4||e.isVector2||e.isVector3||e.isVector4||e.isTexture)?b[c][d]=e.clone():Array.isArray(e)?b[c][d]=e.slice():b[c][d]=e}}return b}},X={alphamap_fragment:"#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif\n",alphamap_pars_fragment:"#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif\n",
-alphatest_fragment:"#ifdef ALPHATEST\n\tif ( diffuseColor.a < ALPHATEST ) discard;\n#endif\n",aomap_fragment:"#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.specularRoughness );\n\t#endif\n#endif\n",
-aomap_pars_fragment:"#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif",begin_vertex:"\nvec3 transformed = vec3( position );\n",beginnormal_vertex:"\nvec3 objectNormal = vec3( normal );\n",bsdfs:"float punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\tif( decayExponent > 0.0 ) {\n#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\tfloat maxDistanceCutoffFactor = pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\treturn distanceFalloff * maxDistanceCutoffFactor;\n#else\n\t\treturn pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );\n#endif\n\t}\n\treturn 1.0;\n}\nvec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\treturn ( 1.0 - specularColor ) * fresnel + specularColor;\n}\nfloat G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\tfloat gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\treturn 1.0 / ( gl * gv );\n}\nfloat G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNL = saturate( dot( geometry.normal, incidentLight.direction ) );\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( G * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE  = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS  = 0.5 / LUT_SIZE;\n\tfloat theta = acos( dot( N, V ) );\n\tvec2 uv = vec2(\n\t\tsqrt( saturate( roughness ) ),\n\t\tsaturate( theta / ( 0.5 * PI ) ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.86267 + (0.49788 + 0.01436 * y ) * y;\n\tfloat b = 3.45068 + (4.18814 + y) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = (x > 0.0) ? v : 0.5 * inversesqrt( 1.0 - x * x ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transpose( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tvec3 result = vec3( LTC_ClippedSphereFormFactor( vectorFormFactor ) );\n\treturn result;\n}\nvec3 BRDF_Specular_GGX_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness ) {\n\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\tvec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\n\treturn specularColor * AB.x + AB.y;\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );\n\tfloat dotNH = saturate( dot( geometry.normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentLight.direction, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, dotLH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\nfloat GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {\n\treturn ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );\n}\nfloat BlinnExponentToGGXRoughness( const in float blinnExponent ) {\n\treturn sqrt( 2.0 / ( blinnExponent + 2.0 ) );\n}\n",
-bumpmap_pars_fragment:"#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {\n\t\tvec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );\n\t\tvec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 );\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif\n",
-clipping_planes_fragment:"#if NUM_CLIPPING_PLANES > 0\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; ++ i ) {\n\t\tvec4 plane = clippingPlanes[ i ];\n\t\tif ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t\t\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; ++ i ) {\n\t\t\tvec4 plane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\tif ( clipped ) discard;\n\t\n\t#endif\n#endif\n",
-clipping_planes_pars_fragment:"#if NUM_CLIPPING_PLANES > 0\n\t#if ! defined( PHYSICAL ) && ! defined( PHONG )\n\t\tvarying vec3 vViewPosition;\n\t#endif\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif\n",clipping_planes_pars_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvarying vec3 vViewPosition;\n#endif\n",clipping_planes_vertex:"#if NUM_CLIPPING_PLANES > 0 && ! defined( PHYSICAL ) && ! defined( PHONG )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n",
-color_fragment:"#ifdef USE_COLOR\n\tdiffuseColor.rgb *= vColor;\n#endif",color_pars_fragment:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif\n",color_pars_vertex:"#ifdef USE_COLOR\n\tvarying vec3 vColor;\n#endif",color_vertex:"#ifdef USE_COLOR\n\tvColor.xyz = color.xyz;\n#endif",common:"#define PI 3.14159265359\n#define PI2 6.28318530718\n#define PI_HALF 1.5707963267949\n#define RECIPROCAL_PI 0.31830988618\n#define RECIPROCAL_PI2 0.15915494\n#define LOG2 1.442695\n#define EPSILON 1e-6\n#define saturate(a) clamp( a, 0.0, 1.0 )\n#define whiteCompliment(a) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract(sin(sn) * c);\n}\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nvec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\tfloat distance = dot( planeNormal, point - pointOnPlane );\n\treturn - distance * planeNormal + point;\n}\nfloat sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn sign( dot( point - pointOnPlane, planeNormal ) );\n}\nvec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {\n\treturn lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;\n}\nmat3 transpose( const in mat3 v ) {\n\tmat3 tmp;\n\ttmp[0] = vec3(v[0].x, v[1].x, v[2].x);\n\ttmp[1] = vec3(v[0].y, v[1].y, v[2].y);\n\ttmp[2] = vec3(v[0].z, v[1].z, v[2].z);\n\treturn tmp;\n}\n",
-cube_uv_reflection_fragment:"#ifdef ENVMAP_TYPE_CUBE_UV\n#define cubeUV_textureSize (1024.0)\nint getFaceFromDirection(vec3 direction) {\n\tvec3 absDirection = abs(direction);\n\tint face = -1;\n\tif( absDirection.x > absDirection.z ) {\n\t\tif(absDirection.x > absDirection.y )\n\t\t\tface = direction.x > 0.0 ? 0 : 3;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\telse {\n\t\tif(absDirection.z > absDirection.y )\n\t\t\tface = direction.z > 0.0 ? 2 : 5;\n\t\telse\n\t\t\tface = direction.y > 0.0 ? 1 : 4;\n\t}\n\treturn face;\n}\n#define cubeUV_maxLods1  (log2(cubeUV_textureSize*0.25) - 1.0)\n#define cubeUV_rangeClamp (exp2((6.0 - 1.0) * 2.0))\nvec2 MipLevelInfo( vec3 vec, float roughnessLevel, float roughness ) {\n\tfloat scale = exp2(cubeUV_maxLods1 - roughnessLevel);\n\tfloat dxRoughness = dFdx(roughness);\n\tfloat dyRoughness = dFdy(roughness);\n\tvec3 dx = dFdx( vec * scale * dxRoughness );\n\tvec3 dy = dFdy( vec * scale * dyRoughness );\n\tfloat d = max( dot( dx, dx ), dot( dy, dy ) );\n\td = clamp(d, 1.0, cubeUV_rangeClamp);\n\tfloat mipLevel = 0.5 * log2(d);\n\treturn vec2(floor(mipLevel), fract(mipLevel));\n}\n#define cubeUV_maxLods2 (log2(cubeUV_textureSize*0.25) - 2.0)\n#define cubeUV_rcpTextureSize (1.0 / cubeUV_textureSize)\nvec2 getCubeUV(vec3 direction, float roughnessLevel, float mipLevel) {\n\tmipLevel = roughnessLevel > cubeUV_maxLods2 - 3.0 ? 0.0 : mipLevel;\n\tfloat a = 16.0 * cubeUV_rcpTextureSize;\n\tvec2 exp2_packed = exp2( vec2( roughnessLevel, mipLevel ) );\n\tvec2 rcp_exp2_packed = vec2( 1.0 ) / exp2_packed;\n\tfloat powScale = exp2_packed.x * exp2_packed.y;\n\tfloat scale = rcp_exp2_packed.x * rcp_exp2_packed.y * 0.25;\n\tfloat mipOffset = 0.75*(1.0 - rcp_exp2_packed.y) * rcp_exp2_packed.x;\n\tbool bRes = mipLevel == 0.0;\n\tscale =  bRes && (scale < a) ? a : scale;\n\tvec3 r;\n\tvec2 offset;\n\tint face = getFaceFromDirection(direction);\n\tfloat rcpPowScale = 1.0 / powScale;\n\tif( face == 0) {\n\t\tr = vec3(direction.x, -direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 1) {\n\t\tr = vec3(direction.y, direction.x, direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 2) {\n\t\tr = vec3(direction.z, direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.75 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? a : offset.y;\n\t}\n\telse if( face == 3) {\n\t\tr = vec3(direction.x, direction.z, direction.y);\n\t\toffset = vec2(0.0+mipOffset,0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse if( face == 4) {\n\t\tr = vec3(direction.y, direction.x, -direction.z);\n\t\toffset = vec2(scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\telse {\n\t\tr = vec3(direction.z, -direction.x, direction.y);\n\t\toffset = vec2(2.0*scale+mipOffset, 0.5 * rcpPowScale);\n\t\toffset.y = bRes && (offset.y < 2.0*a) ? 0.0 : offset.y;\n\t}\n\tr = normalize(r);\n\tfloat texelOffset = 0.5 * cubeUV_rcpTextureSize;\n\tvec2 s = ( r.yz / abs( r.x ) + vec2( 1.0 ) ) * 0.5;\n\tvec2 base = offset + vec2( texelOffset );\n\treturn base + s * ( scale - 2.0 * texelOffset );\n}\n#define cubeUV_maxLods3 (log2(cubeUV_textureSize*0.25) - 3.0)\nvec4 textureCubeUV(vec3 reflectedDirection, float roughness ) {\n\tfloat roughnessVal = roughness* cubeUV_maxLods3;\n\tfloat r1 = floor(roughnessVal);\n\tfloat r2 = r1 + 1.0;\n\tfloat t = fract(roughnessVal);\n\tvec2 mipInfo = MipLevelInfo(reflectedDirection, r1, roughness);\n\tfloat s = mipInfo.y;\n\tfloat level0 = mipInfo.x;\n\tfloat level1 = level0 + 1.0;\n\tlevel1 = level1 > 5.0 ? 5.0 : level1;\n\tlevel0 += min( floor( s + 0.5 ), 5.0 );\n\tvec2 uv_10 = getCubeUV(reflectedDirection, r1, level0);\n\tvec4 color10 = envMapTexelToLinear(texture2D(envMap, uv_10));\n\tvec2 uv_20 = getCubeUV(reflectedDirection, r2, level0);\n\tvec4 color20 = envMapTexelToLinear(texture2D(envMap, uv_20));\n\tvec4 result = mix(color10, color20, t);\n\treturn vec4(result.rgb, 1.0);\n}\n#endif\n",
-defaultnormal_vertex:"vec3 transformedNormal = normalMatrix * objectNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n",displacementmap_pars_vertex:"#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif\n",displacementmap_vertex:"#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, uv ).x * displacementScale + displacementBias );\n#endif\n",
-emissivemap_fragment:"#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\temissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif\n",emissivemap_pars_fragment:"#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif\n",encodings_fragment:"  gl_FragColor = linearToOutputTexel( gl_FragColor );\n",encodings_pars_fragment:"\nvec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 GammaToLinear( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );\n}\nvec4 LinearToGamma( in vec4 value, in float gammaFactor ) {\n\treturn vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );\n}\nvec4 sRGBToLinear( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.w );\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.w );\n}\nvec4 RGBEToLinear( in vec4 value ) {\n\treturn vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );\n}\nvec4 LinearToRGBE( in vec4 value ) {\n\tfloat maxComponent = max( max( value.r, value.g ), value.b );\n\tfloat fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );\n\treturn vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );\n}\nvec4 RGBMToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.xyz * value.w * maxRange, 1.0 );\n}\nvec4 LinearToRGBM( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\n\tfloat M      = clamp( maxRGB / maxRange, 0.0, 1.0 );\n\tM            = ceil( M * 255.0 ) / 255.0;\n\treturn vec4( value.rgb / ( M * maxRange ), M );\n}\nvec4 RGBDToLinear( in vec4 value, in float maxRange ) {\n\treturn vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );\n}\nvec4 LinearToRGBD( in vec4 value, in float maxRange ) {\n\tfloat maxRGB = max( value.x, max( value.g, value.b ) );\n\tfloat D      = max( maxRange / maxRGB, 1.0 );\n\tD            = min( floor( D ) / 255.0, 1.0 );\n\treturn vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );\n}\nconst mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );\nvec4 LinearToLogLuv( in vec4 value )  {\n\tvec3 Xp_Y_XYZp = value.rgb * cLogLuvM;\n\tXp_Y_XYZp = max(Xp_Y_XYZp, vec3(1e-6, 1e-6, 1e-6));\n\tvec4 vResult;\n\tvResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;\n\tfloat Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;\n\tvResult.w = fract(Le);\n\tvResult.z = (Le - (floor(vResult.w*255.0))/255.0)/255.0;\n\treturn vResult;\n}\nconst mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );\nvec4 LogLuvToLinear( in vec4 value ) {\n\tfloat Le = value.z * 255.0 + value.w;\n\tvec3 Xp_Y_XYZp;\n\tXp_Y_XYZp.y = exp2((Le - 127.0) / 2.0);\n\tXp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;\n\tXp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;\n\tvec3 vRGB = Xp_Y_XYZp.rgb * cLogLuvInverseM;\n\treturn vec4( max(vRGB, 0.0), 1.0 );\n}\n",
-envmap_fragment:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvec3 cameraToVertex = normalize( vWorldPosition - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\tvec2 sampleUV;\n\t\tsampleUV.y = asin( flipNormal * reflectVec.y ) * RECIPROCAL_PI + 0.5;\n\t\tsampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\tvec4 envColor = texture2D( envMap, sampleUV );\n\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\tvec3 reflectView = flipNormal * normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );\n\t\tvec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\tenvColor = envMapTexelToLinear( envColor );\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif\n",
-envmap_pars_fragment:"#if defined( USE_ENVMAP ) || defined( PHYSICAL )\n\tuniform float reflectivity;\n\tuniform float envMapIntensity;\n#endif\n#ifdef USE_ENVMAP\n\t#if ! defined( PHYSICAL ) && ( defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) )\n\t\tvarying vec3 vWorldPosition;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\tuniform float flipEnvMap;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( PHYSICAL )\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif\n",
-envmap_pars_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif\n",envmap_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif\n",
-fog_vertex:"\n#ifdef USE_FOG\nfogDepth = -mvPosition.z;\n#endif",fog_pars_vertex:"#ifdef USE_FOG\n  varying float fogDepth;\n#endif\n",fog_fragment:"#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = whiteCompliment( exp2( - fogDensity * fogDensity * fogDepth * fogDepth * LOG2 ) );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, fogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif\n",fog_pars_fragment:"#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float fogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif\n",
-gradientmap_pars_fragment:"#ifdef TOON\n\tuniform sampler2D gradientMap;\n\tvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\t\tfloat dotNL = dot( normal, lightDirection );\n\t\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t\t#ifdef USE_GRADIENTMAP\n\t\t\treturn texture2D( gradientMap, coord ).rgb;\n\t\t#else\n\t\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t\t#endif\n\t}\n#endif\n",lightmap_fragment:"#ifdef USE_LIGHTMAP\n\treflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n#endif\n",
-lightmap_pars_fragment:"#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif",lights_lambert_vertex:"vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\n#if NUM_POINT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_DIR_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = PI * directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( -dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvLightFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );\n\t\t#endif\n\t}\n#endif\n",
-lights_pars:"uniform vec3 ambientLightColor;\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treturn irradiance;\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tdirectLight.color = directionalLight.color;\n\t\tdirectLight.direction = directionalLight.direction;\n\t\tdirectLight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tdirectLight.color = pointLight.color;\n\t\tdirectLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );\n\t\tdirectLight.visible = ( directLight.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t\tint shadow;\n\t\tfloat shadowBias;\n\t\tfloat shadowRadius;\n\t\tvec2 shadowMapSize;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight  ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tdirectLight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( directLight.direction, spotLight.direction );\n\t\tif ( angleCos > spotLight.coneCos ) {\n\t\t\tfloat spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\t\tdirectLight.color = spotLight.color;\n\t\t\tdirectLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tdirectLight.visible = true;\n\t\t} else {\n\t\t\tdirectLight.color = vec3( 0.0 );\n\t\t\tdirectLight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltcMat;\tuniform sampler2D ltcMag;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {\n\t\tfloat dotNL = dot( geometry.normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tirradiance *= PI;\n\t\t#endif\n\t\treturn irradiance;\n\t}\n#endif\n#if defined( USE_ENVMAP ) && defined( PHYSICAL )\n\tvec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {\n\t\tvec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );\n\t\t\tvec4 envMapColor = textureCubeUV( queryVec, 1.0 );\n\t\t#else\n\t\t\tvec4 envMapColor = vec4( 0.0 );\n\t\t#endif\n\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t}\n\tfloat getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\tfloat maxMIPLevelScalar = float( maxMIPLevel );\n\t\tfloat desiredMIPLevel = maxMIPLevelScalar - 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );\n\t\treturn clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );\n\t}\n\tvec3 getLightProbeIndirectRadiance( const in GeometricContext geometry, const in float blinnShininessExponent, const in int maxMIPLevel ) {\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( -geometry.viewDir, geometry.normal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( -geometry.viewDir, geometry.normal, refractionRatio );\n\t\t#endif\n\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\tfloat specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );\n\t\t#ifdef ENVMAP_TYPE_CUBE\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );\n\t\t\tvec4 envMapColor = textureCubeUV(queryReflectVec, BlinnExponentToGGXRoughness(blinnShininessExponent));\n\t\t#elif defined( ENVMAP_TYPE_EQUIREC )\n\t\t\tvec2 sampleUV;\n\t\t\tsampleUV.y = saturate( reflectVec.y * 0.5 + 0.5 );\n\t\t\tsampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#elif defined( ENVMAP_TYPE_SPHERE )\n\t\t\tvec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );\n\t\t\t#ifdef TEXTURE_LOD_EXT\n\t\t\t\tvec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#else\n\t\t\t\tvec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );\n\t\t\t#endif\n\t\t\tenvMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;\n\t\t#endif\n\t\treturn envMapColor.rgb * envMapIntensity;\n\t}\n#endif\n",
-lights_phong_fragment:"BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;\n",lights_phong_pars_fragment:"varying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\nstruct BlinnPhongMaterial {\n\tvec3\tdiffuseColor;\n\tvec3\tspecularColor;\n\tfloat\tspecularShininess;\n\tfloat\tspecularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifdef TOON\n\t\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\t#else\n\t\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\t\tvec3 irradiance = dotNL * directLight.color;\n\t#endif\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)\n",
-lights_physical_fragment:"PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.specularRoughness = clamp( roughnessFactor, 0.04, 1.0 );\n#ifdef STANDARD\n\tmaterial.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.clearCoat = saturate( clearCoat );\tmaterial.clearCoatRoughness = clamp( clearCoatRoughness, 0.04, 1.0 );\n#endif\n",
-lights_physical_pars_fragment:"struct PhysicalMaterial {\n\tvec3\tdiffuseColor;\n\tfloat\tspecularRoughness;\n\tvec3\tspecularColor;\n\t#ifndef STANDARD\n\t\tfloat clearCoat;\n\t\tfloat clearCoatRoughness;\n\t#endif\n};\n#define MAXIMUM_SPECULAR_COEFFICIENT 0.16\n#define DEFAULT_SPECULAR_COEFFICIENT 0.04\nfloat clearCoatDHRApprox( const in float roughness, const in float dotNL ) {\n\treturn DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.specularRoughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos - halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos + halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos + halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos - halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tfloat norm = texture2D( ltcMag, uv ).a;\n\t\tvec4 t = texture2D( ltcMat, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3(   1,   0, t.y ),\n\t\t\tvec3(   0, t.z,   0 ),\n\t\t\tvec3( t.w,   0, t.x )\n\t\t);\n\t\treflectedLight.directSpecular += lightColor * material.specularColor * norm * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\tirradiance *= PI;\n\t#endif\n\t#ifndef STANDARD\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.directSpecular += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry, material.specularColor, material.specularRoughness );\n\treflectedLight.directDiffuse += ( 1.0 - clearCoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\t#ifndef STANDARD\n\t\treflectedLight.directSpecular += irradiance * material.clearCoat * BRDF_Specular_GGX( directLight, geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 clearCoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t#ifndef STANDARD\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\tfloat dotNL = dotNV;\n\t\tfloat clearCoatDHR = material.clearCoat * clearCoatDHRApprox( material.clearCoatRoughness, dotNL );\n\t#else\n\t\tfloat clearCoatDHR = 0.0;\n\t#endif\n\treflectedLight.indirectSpecular += ( 1.0 - clearCoatDHR ) * radiance * BRDF_Specular_GGX_Environment( geometry, material.specularColor, material.specularRoughness );\n\t#ifndef STANDARD\n\t\treflectedLight.indirectSpecular += clearCoatRadiance * material.clearCoat * BRDF_Specular_GGX_Environment( geometry, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearCoatRoughness );\n\t#endif\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\n#define Material_BlinnShininessExponent( material )   GGXRoughnessToBlinnExponent( material.specularRoughness )\n#define Material_ClearCoat_BlinnShininessExponent( material )   GGXRoughnessToBlinnExponent( material.clearCoatRoughness )\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}\n",
-lights_template:"\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = normalize( vViewPosition );\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointDirectLightIrradiance( pointLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( pointLight.shadow, directLight.visible ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotDirectLightIrradiance( spotLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( spotLight.shadow, directLight.visible ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );\n\t\t#ifdef USE_SHADOWMAP\n\t\tdirectLight.color *= all( bvec2( directionalLight.shadow, directLight.visible ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\t#ifdef USE_LIGHTMAP\n\t\tvec3 lightMapIrradiance = texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t\t#ifndef PHYSICALLY_CORRECT_LIGHTS\n\t\t\tlightMapIrradiance *= PI;\n\t\t#endif\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );\n\t\t}\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( PHYSICAL ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tirradiance += getLightProbeIndirectIrradiance( geometry, 8 );\n\t#endif\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tvec3 radiance = getLightProbeIndirectRadiance( geometry, Material_BlinnShininessExponent( material ), 8 );\n\t#ifndef STANDARD\n\t\tvec3 clearCoatRadiance = getLightProbeIndirectRadiance( geometry, Material_ClearCoat_BlinnShininessExponent( material ), 8 );\n\t#else\n\t\tvec3 clearCoatRadiance = vec3( 0.0 );\n\t#endif\n\tRE_IndirectSpecular( radiance, clearCoatRadiance, geometry, material, reflectedLight );\n#endif\n",
-logdepthbuf_fragment:"#if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT)\n\tgl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5;\n#endif",logdepthbuf_pars_fragment:"#ifdef USE_LOGDEPTHBUF\n\tuniform float logDepthBufFC;\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#endif\n#endif\n",logdepthbuf_pars_vertex:"#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t#endif\n\tuniform float logDepthBufFC;\n#endif",logdepthbuf_vertex:"#ifdef USE_LOGDEPTHBUF\n\tgl_Position.z = log2(max( EPSILON, gl_Position.w + 1.0 )) * logDepthBufFC;\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t#else\n\t\tgl_Position.z = (gl_Position.z - 1.0) * gl_Position.w;\n\t#endif\n#endif\n",
-map_fragment:"#ifdef USE_MAP\n\tvec4 texelColor = texture2D( map, vUv );\n\ttexelColor = mapTexelToLinear( texelColor );\n\tdiffuseColor *= texelColor;\n#endif\n",map_pars_fragment:"#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n",map_particle_fragment:"#ifdef USE_MAP\n\tvec4 mapTexel = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) * offsetRepeat.zw + offsetRepeat.xy );\n\tdiffuseColor *= mapTexelToLinear( mapTexel );\n#endif\n",map_particle_pars_fragment:"#ifdef USE_MAP\n\tuniform vec4 offsetRepeat;\n\tuniform sampler2D map;\n#endif\n",
-metalnessmap_fragment:"float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif\n",metalnessmap_pars_fragment:"#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif",morphnormal_vertex:"#ifdef USE_MORPHNORMALS\n\tobjectNormal += ( morphNormal0 - normal ) * morphTargetInfluences[ 0 ];\n\tobjectNormal += ( morphNormal1 - normal ) * morphTargetInfluences[ 1 ];\n\tobjectNormal += ( morphNormal2 - normal ) * morphTargetInfluences[ 2 ];\n\tobjectNormal += ( morphNormal3 - normal ) * morphTargetInfluences[ 3 ];\n#endif\n",
-morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n\t#ifndef USE_MORPHNORMALS\n\tuniform float morphTargetInfluences[ 8 ];\n\t#else\n\tuniform float morphTargetInfluences[ 4 ];\n\t#endif\n#endif",morphtarget_vertex:"#ifdef USE_MORPHTARGETS\n\ttransformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\n\ttransformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\n\ttransformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\n\ttransformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\n\t#ifndef USE_MORPHNORMALS\n\ttransformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\n\ttransformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\n\ttransformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\n\ttransformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\n\t#endif\n#endif\n",
-normal_flip:"#ifdef DOUBLE_SIDED\n\tfloat flipNormal = ( float( gl_FrontFacing ) * 2.0 - 1.0 );\n#else\n\tfloat flipNormal = 1.0;\n#endif\n",normal_fragment:"#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal ) * flipNormal;\n#endif\n#ifdef USE_NORMALMAP\n\tnormal = perturbNormal2Arb( -vViewPosition, normal );\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );\n#endif\n",
-normalmap_pars_fragment:"#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {\n\t\tvec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );\n\t\tvec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tvec3 S = normalize( q0 * st1.t - q1 * st0.t );\n\t\tvec3 T = normalize( -q0 * st1.s + q1 * st0.s );\n\t\tvec3 N = normalize( surf_norm );\n\t\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t\tmapN.xy = normalScale * mapN.xy;\n\t\tmat3 tsn = mat3( S, T, N );\n\t\treturn normalize( tsn * mapN );\n\t}\n#endif\n",
-packing:"vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 1.0 - 2.0 * rgb.xyz;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256.,  256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn (( near + viewZ ) * far ) / (( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}\n",
-premultiplied_alpha_fragment:"#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif\n",project_vertex:"vec4 mvPosition = modelViewMatrix * vec4( transformed, 1.0 );\ngl_Position = projectionMatrix * mvPosition;\n",dithering_fragment:"#if defined( DITHERING )\n  gl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif\n",dithering_pars_fragment:"#if defined( DITHERING )\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif\n",
-roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif\n",roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tfloat texture2DShadowLerp( sampler2D depths, vec2 size, vec2 uv, float compare ) {\n\t\tconst vec2 offset = vec2( 0.0, 1.0 );\n\t\tvec2 texelSize = vec2( 1.0 ) / size;\n\t\tvec2 centroidUV = floor( uv * size + 0.5 ) / size;\n\t\tfloat lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );\n\t\tfloat lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );\n\t\tfloat rb = texture2DCompare( depths, centroidUV + texelSize * offset.yx, compare );\n\t\tfloat rt = texture2DCompare( depths, centroidUV + texelSize * offset.yy, compare );\n\t\tvec2 f = fract( uv * size + 0.5 );\n\t\tfloat a = mix( lb, lt, f.y );\n\t\tfloat b = mix( rb, rt, f.y );\n\t\tfloat c = mix( a, b, f.x );\n\t\treturn c;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tshadow = (\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DShadowLerp( shadowMap, shadowMapSize, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\tfloat dp = ( length( lightToPosition ) - shadowBias ) / 1000.0;\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif\n",
-shadowmap_pars_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHTS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHTS ];\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHTS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHTS ];\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHTS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHTS ];\n\t#endif\n#endif\n",
-shadowmap_vertex:"#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;\n\t}\n\t#endif\n#endif\n",
-shadowmask_pars_fragment:"float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHTS > 0\n\tDirectionalLight directionalLight;\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tshadow *= bool( directionalLight.shadow ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_SPOT_LIGHTS > 0\n\tSpotLight spotLight;\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tshadow *= bool( spotLight.shadow ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#if NUM_POINT_LIGHTS > 0\n\tPointLight pointLight;\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tshadow *= bool( pointLight.shadow ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ] ) : 1.0;\n\t}\n\t#endif\n\t#endif\n\treturn shadow;\n}\n",
-skinbase_vertex:"#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\t#ifdef BONE_TEXTURE\n\t\tuniform sampler2D boneTexture;\n\t\tuniform int boneTextureSize;\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tfloat j = i * 4.0;\n\t\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\t\ty = dy * ( y + 0.5 );\n\t\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\t\treturn bone;\n\t\t}\n\t#else\n\t\tuniform mat4 boneMatrices[ MAX_BONES ];\n\t\tmat4 getBoneMatrix( const in float i ) {\n\t\t\tmat4 bone = boneMatrices[ int(i) ];\n\t\t\treturn bone;\n\t\t}\n\t#endif\n#endif\n",
-skinning_vertex:"#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif\n",skinnormal_vertex:"#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix  = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n#endif\n",
-specularmap_fragment:"float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif",specularmap_pars_fragment:"#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif",tonemapping_fragment:"#if defined( TONE_MAPPING )\n  gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif\n",tonemapping_pars_fragment:"#define saturate(a) clamp( a, 0.0, 1.0 )\nuniform float toneMappingExposure;\nuniform float toneMappingWhitePoint;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\n#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )\nvec3 Uncharted2ToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\n",
-uv_pars_fragment:"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n#endif",uv_pars_vertex:"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvarying vec2 vUv;\n\tuniform vec4 offsetRepeat;\n#endif\n",
-uv_vertex:"#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )\n\tvUv = uv * offsetRepeat.zw + offsetRepeat.xy;\n#endif",uv2_pars_fragment:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif",uv2_pars_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n#endif",
-uv2_vertex:"#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = uv2;\n#endif",worldpos_vertex:"#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n#endif\n",cube_frag:"uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n\tgl_FragColor.a *= opacity;\n}\n",
-cube_vert:"varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}\n",depth_frag:"#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <logdepthbuf_fragment>\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}\n",
-depth_vert:"#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n}\n",
-distanceRGBA_frag:"uniform vec3 lightPos;\nvarying vec4 vWorldPosition;\n#include <common>\n#include <packing>\n#include <clipping_planes_pars_fragment>\nvoid main () {\n\t#include <clipping_planes_fragment>\n\tgl_FragColor = packDepthToRGBA( length( vWorldPosition.xyz - lightPos.xyz ) / 1000.0 );\n}\n",distanceRGBA_vert:"varying vec4 vWorldPosition;\n#include <common>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <skinbase_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition;\n}\n",
-equirect_frag:"uniform sampler2D tEquirect;\nuniform float tFlip;\nvarying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvec3 direction = normalize( vWorldPosition );\n\tvec2 sampleUV;\n\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}\n",equirect_vert:"varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}\n",
-linedashed_frag:"uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <color_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n",
-linedashed_vert:"uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\tvLineDistance = scale * lineDistance;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}\n",
-meshbasic_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\treflectedLight.indirectDiffuse += texture2D( lightMap, vUv2 ).xyz * lightMapIntensity;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include <aomap_fragment>\n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include <normal_flip>\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n",
-meshbasic_vert:"#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_ENVMAP\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <envmap_vertex>\n\t#include <fog_vertex>\n}\n",
-meshlambert_frag:"uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <bsdfs>\n#include <lights_pars>\n#include <fog_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <emissivemap_fragment>\n\treflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );\n\t#include <lightmap_fragment>\n\treflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <normal_flip>\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}\n",
-meshlambert_vert:"#define LAMBERT\nvarying vec3 vLightFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <bsdfs>\n#include <lights_pars>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <lights_lambert_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n",
-meshphong_frag:"#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <gradientmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars>\n#include <lights_phong_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_flip>\n\t#include <normal_fragment>\n\t#include <emissivemap_fragment>\n\t#include <lights_phong_fragment>\n\t#include <lights_template>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}\n",
-meshphong_vert:"#define PHONG\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n",
-meshphysical_frag:"#define PHYSICAL\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifndef STANDARD\n\tuniform float clearCoat;\n\tuniform float clearCoatRoughness;\n#endif\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <cube_uv_reflection_fragment>\n#include <lights_pars>\n#include <lights_physical_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <roughnessmap_fragment>\n\t#include <metalnessmap_fragment>\n\t#include <normal_flip>\n\t#include <normal_fragment>\n\t#include <emissivemap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_template>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}\n",
-meshphysical_vert:"#define PHYSICAL\nvarying vec3 vViewPosition;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n",
-normal_frag:"#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <packing>\n#include <uv_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\nvoid main() {\n\t#include <logdepthbuf_fragment>\n\t#include <normal_flip>\n\t#include <normal_fragment>\n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n}\n",
-normal_vert:"#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}\n",
-points_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <fog_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\tgl_FragColor = vec4( outgoingLight, diffuseColor.a );\n\t#include <premultiplied_alpha_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}\n",
-points_vert:"uniform float size;\nuniform float scale;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\t#ifdef USE_SIZEATTENUATION\n\t\tgl_PointSize = size * ( scale / - mvPosition.z );\n\t#else\n\t\tgl_PointSize = size;\n\t#endif\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}\n",
-shadow_frag:"uniform float opacity;\n#include <common>\n#include <packing>\n#include <bsdfs>\n#include <lights_pars>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\nvoid main() {\n\tgl_FragColor = vec4( 0.0, 0.0, 0.0, opacity * ( 1.0 - getShadowMask() ) );\n}\n",shadow_vert:"#include <shadowmap_pars_vertex>\nvoid main() {\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n}\n"},$a={basic:{uniforms:Ca.merge([R.common,
-R.aomap,R.lightmap,R.fog]),vertexShader:X.meshbasic_vert,fragmentShader:X.meshbasic_frag},lambert:{uniforms:Ca.merge([R.common,R.aomap,R.lightmap,R.emissivemap,R.fog,R.lights,{emissive:{value:new G(0)}}]),vertexShader:X.meshlambert_vert,fragmentShader:X.meshlambert_frag},phong:{uniforms:Ca.merge([R.common,R.aomap,R.lightmap,R.emissivemap,R.bumpmap,R.normalmap,R.displacementmap,R.gradientmap,R.fog,R.lights,{emissive:{value:new G(0)},specular:{value:new G(1118481)},shininess:{value:30}}]),vertexShader:X.meshphong_vert,
-fragmentShader:X.meshphong_frag},standard:{uniforms:Ca.merge([R.common,R.aomap,R.lightmap,R.emissivemap,R.bumpmap,R.normalmap,R.displacementmap,R.roughnessmap,R.metalnessmap,R.fog,R.lights,{emissive:{value:new G(0)},roughness:{value:.5},metalness:{value:.5},envMapIntensity:{value:1}}]),vertexShader:X.meshphysical_vert,fragmentShader:X.meshphysical_frag},points:{uniforms:Ca.merge([R.points,R.fog]),vertexShader:X.points_vert,fragmentShader:X.points_frag},dashed:{uniforms:Ca.merge([R.common,R.fog,{scale:{value:1},
-dashSize:{value:1},totalSize:{value:2}}]),vertexShader:X.linedashed_vert,fragmentShader:X.linedashed_frag},depth:{uniforms:Ca.merge([R.common,R.displacementmap]),vertexShader:X.depth_vert,fragmentShader:X.depth_frag},normal:{uniforms:Ca.merge([R.common,R.bumpmap,R.normalmap,R.displacementmap,{opacity:{value:1}}]),vertexShader:X.normal_vert,fragmentShader:X.normal_frag},cube:{uniforms:{tCube:{value:null},tFlip:{value:-1},opacity:{value:1}},vertexShader:X.cube_vert,fragmentShader:X.cube_frag},equirect:{uniforms:{tEquirect:{value:null},
-tFlip:{value:-1}},vertexShader:X.equirect_vert,fragmentShader:X.equirect_frag},distanceRGBA:{uniforms:{lightPos:{value:new n}},vertexShader:X.distanceRGBA_vert,fragmentShader:X.distanceRGBA_frag}};$a.physical={uniforms:Ca.merge([$a.standard.uniforms,{clearCoat:{value:0},clearCoatRoughness:{value:0}}]),vertexShader:X.meshphysical_vert,fragmentShader:X.meshphysical_frag};Object.assign(fd.prototype,{set:function(a,b){this.min.copy(a);this.max.copy(b);return this},setFromPoints:function(a){this.makeEmpty();
-for(var b=0,c=a.length;b<c;b++)this.expandByPoint(a[b]);return this},setFromCenterAndSize:function(){var a=new C;return function(b,c){var d=a.copy(c).multiplyScalar(.5);this.min.copy(b).sub(d);this.max.copy(b).add(d);return this}}(),clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.min.copy(a.min);this.max.copy(a.max);return this},makeEmpty:function(){this.min.x=this.min.y=Infinity;this.max.x=this.max.y=-Infinity;return this},isEmpty:function(){return this.max.x<this.min.x||
-this.max.y<this.min.y},getCenter:function(a){a=a||new C;return this.isEmpty()?a.set(0,0):a.addVectors(this.min,this.max).multiplyScalar(.5)},getSize:function(a){a=a||new C;return this.isEmpty()?a.set(0,0):a.subVectors(this.max,this.min)},expandByPoint:function(a){this.min.min(a);this.max.max(a);return this},expandByVector:function(a){this.min.sub(a);this.max.add(a);return this},expandByScalar:function(a){this.min.addScalar(-a);this.max.addScalar(a);return this},containsPoint:function(a){return a.x<
-this.min.x||a.x>this.max.x||a.y<this.min.y||a.y>this.max.y?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y},getParameter:function(a,b){return(b||new C).set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y))},intersectsBox:function(a){return a.max.x<this.min.x||a.min.x>this.max.x||a.max.y<this.min.y||a.min.y>this.max.y?!1:!0},clampPoint:function(a,b){return(b||new C).copy(a).clamp(this.min,this.max)},
-distanceToPoint:function(){var a=new C;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),intersect:function(a){this.min.max(a.min);this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)}});var Jf=0;Object.assign(U.prototype,xa.prototype,{isMaterial:!0,onBeforeCompile:function(){},
-setValues:function(a){if(void 0!==a)for(var b in a){var c=a[b];if(void 0===c)console.warn("THREE.Material: '"+b+"' parameter is undefined.");else{var d=this[b];void 0===d?console.warn("THREE."+this.type+": '"+b+"' is not a property of this material."):d&&d.isColor?d.set(c):d&&d.isVector3&&c&&c.isVector3?d.copy(c):this[b]="overdraw"===b?Number(c):c}}},toJSON:function(a){function b(a){var b=[],c;for(c in a){var d=a[c];delete d.metadata;b.push(d)}return b}var c=void 0===a;c&&(a={textures:{},images:{}});
-var d={metadata:{version:4.5,type:"Material",generator:"Material.toJSON"}};d.uuid=this.uuid;d.type=this.type;""!==this.name&&(d.name=this.name);this.color&&this.color.isColor&&(d.color=this.color.getHex());void 0!==this.roughness&&(d.roughness=this.roughness);void 0!==this.metalness&&(d.metalness=this.metalness);this.emissive&&this.emissive.isColor&&(d.emissive=this.emissive.getHex());this.specular&&this.specular.isColor&&(d.specular=this.specular.getHex());void 0!==this.shininess&&(d.shininess=this.shininess);
-void 0!==this.clearCoat&&(d.clearCoat=this.clearCoat);void 0!==this.clearCoatRoughness&&(d.clearCoatRoughness=this.clearCoatRoughness);this.map&&this.map.isTexture&&(d.map=this.map.toJSON(a).uuid);this.alphaMap&&this.alphaMap.isTexture&&(d.alphaMap=this.alphaMap.toJSON(a).uuid);this.lightMap&&this.lightMap.isTexture&&(d.lightMap=this.lightMap.toJSON(a).uuid);this.bumpMap&&this.bumpMap.isTexture&&(d.bumpMap=this.bumpMap.toJSON(a).uuid,d.bumpScale=this.bumpScale);this.normalMap&&this.normalMap.isTexture&&
-(d.normalMap=this.normalMap.toJSON(a).uuid,d.normalScale=this.normalScale.toArray());this.displacementMap&&this.displacementMap.isTexture&&(d.displacementMap=this.displacementMap.toJSON(a).uuid,d.displacementScale=this.displacementScale,d.displacementBias=this.displacementBias);this.roughnessMap&&this.roughnessMap.isTexture&&(d.roughnessMap=this.roughnessMap.toJSON(a).uuid);this.metalnessMap&&this.metalnessMap.isTexture&&(d.metalnessMap=this.metalnessMap.toJSON(a).uuid);this.emissiveMap&&this.emissiveMap.isTexture&&
-(d.emissiveMap=this.emissiveMap.toJSON(a).uuid);this.specularMap&&this.specularMap.isTexture&&(d.specularMap=this.specularMap.toJSON(a).uuid);this.envMap&&this.envMap.isTexture&&(d.envMap=this.envMap.toJSON(a).uuid,d.reflectivity=this.reflectivity);this.gradientMap&&this.gradientMap.isTexture&&(d.gradientMap=this.gradientMap.toJSON(a).uuid);void 0!==this.size&&(d.size=this.size);void 0!==this.sizeAttenuation&&(d.sizeAttenuation=this.sizeAttenuation);1!==this.blending&&(d.blending=this.blending);2!==
-this.shading&&(d.shading=this.shading);0!==this.side&&(d.side=this.side);0!==this.vertexColors&&(d.vertexColors=this.vertexColors);1>this.opacity&&(d.opacity=this.opacity);!0===this.transparent&&(d.transparent=this.transparent);d.depthFunc=this.depthFunc;d.depthTest=this.depthTest;d.depthWrite=this.depthWrite;0<this.alphaTest&&(d.alphaTest=this.alphaTest);!0===this.premultipliedAlpha&&(d.premultipliedAlpha=this.premultipliedAlpha);!0===this.wireframe&&(d.wireframe=this.wireframe);1<this.wireframeLinewidth&&
-(d.wireframeLinewidth=this.wireframeLinewidth);"round"!==this.wireframeLinecap&&(d.wireframeLinecap=this.wireframeLinecap);"round"!==this.wireframeLinejoin&&(d.wireframeLinejoin=this.wireframeLinejoin);d.skinning=this.skinning;d.morphTargets=this.morphTargets;d.dithering=this.dithering;c&&(c=b(a.textures),a=b(a.images),0<c.length&&(d.textures=c),0<a.length&&(d.images=a));return d},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.name=a.name;this.fog=a.fog;this.lights=
-a.lights;this.blending=a.blending;this.side=a.side;this.shading=a.shading;this.vertexColors=a.vertexColors;this.opacity=a.opacity;this.transparent=a.transparent;this.blendSrc=a.blendSrc;this.blendDst=a.blendDst;this.blendEquation=a.blendEquation;this.blendSrcAlpha=a.blendSrcAlpha;this.blendDstAlpha=a.blendDstAlpha;this.blendEquationAlpha=a.blendEquationAlpha;this.depthFunc=a.depthFunc;this.depthTest=a.depthTest;this.depthWrite=a.depthWrite;this.colorWrite=a.colorWrite;this.precision=a.precision;this.polygonOffset=
-a.polygonOffset;this.polygonOffsetFactor=a.polygonOffsetFactor;this.polygonOffsetUnits=a.polygonOffsetUnits;this.dithering=a.dithering;this.alphaTest=a.alphaTest;this.premultipliedAlpha=a.premultipliedAlpha;this.overdraw=a.overdraw;this.visible=a.visible;this.clipShadows=a.clipShadows;this.clipIntersection=a.clipIntersection;a=a.clippingPlanes;var b=null;if(null!==a)for(var c=a.length,b=Array(c),d=0;d!==c;++d)b[d]=a[d].clone();this.clippingPlanes=b;return this},dispose:function(){this.dispatchEvent({type:"dispose"})}});
-ra.prototype=Object.create(U.prototype);ra.prototype.constructor=ra;ra.prototype.isShaderMaterial=!0;ra.prototype.copy=function(a){U.prototype.copy.call(this,a);this.fragmentShader=a.fragmentShader;this.vertexShader=a.vertexShader;this.uniforms=Ca.clone(a.uniforms);this.defines=a.defines;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.lights=a.lights;this.clipping=a.clipping;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;this.extensions=
-a.extensions;return this};ra.prototype.toJSON=function(a){a=U.prototype.toJSON.call(this,a);a.uniforms=this.uniforms;a.vertexShader=this.vertexShader;a.fragmentShader=this.fragmentShader;return a};Za.prototype=Object.create(U.prototype);Za.prototype.constructor=Za;Za.prototype.isMeshDepthMaterial=!0;Za.prototype.copy=function(a){U.prototype.copy.call(this,a);this.depthPacking=a.depthPacking;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.map=a.map;this.alphaMap=a.alphaMap;this.displacementMap=
-a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;return this};Object.assign(Ra.prototype,{isBox3:!0,set:function(a,b){this.min.copy(a);this.max.copy(b);return this},setFromArray:function(a){for(var b=Infinity,c=Infinity,d=Infinity,e=-Infinity,f=-Infinity,g=-Infinity,h=0,k=a.length;h<k;h+=3){var m=a[h],q=a[h+1],l=a[h+2];m<b&&(b=m);q<c&&(c=q);l<d&&(d=l);m>e&&(e=m);q>f&&(f=q);
-l>g&&(g=l)}this.min.set(b,c,d);this.max.set(e,f,g);return this},setFromBufferAttribute:function(a){for(var b=Infinity,c=Infinity,d=Infinity,e=-Infinity,f=-Infinity,g=-Infinity,h=0,k=a.count;h<k;h++){var m=a.getX(h),q=a.getY(h),l=a.getZ(h);m<b&&(b=m);q<c&&(c=q);l<d&&(d=l);m>e&&(e=m);q>f&&(f=q);l>g&&(g=l)}this.min.set(b,c,d);this.max.set(e,f,g);return this},setFromPoints:function(a){this.makeEmpty();for(var b=0,c=a.length;b<c;b++)this.expandByPoint(a[b]);return this},setFromCenterAndSize:function(){var a=
-new n;return function(b,c){var d=a.copy(c).multiplyScalar(.5);this.min.copy(b).sub(d);this.max.copy(b).add(d);return this}}(),setFromObject:function(a){this.makeEmpty();return this.expandByObject(a)},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.min.copy(a.min);this.max.copy(a.max);return this},makeEmpty:function(){this.min.x=this.min.y=this.min.z=Infinity;this.max.x=this.max.y=this.max.z=-Infinity;return this},isEmpty:function(){return this.max.x<this.min.x||this.max.y<
-this.min.y||this.max.z<this.min.z},getCenter:function(a){a=a||new n;return this.isEmpty()?a.set(0,0,0):a.addVectors(this.min,this.max).multiplyScalar(.5)},getSize:function(a){a=a||new n;return this.isEmpty()?a.set(0,0,0):a.subVectors(this.max,this.min)},expandByPoint:function(a){this.min.min(a);this.max.max(a);return this},expandByVector:function(a){this.min.sub(a);this.max.add(a);return this},expandByScalar:function(a){this.min.addScalar(-a);this.max.addScalar(a);return this},expandByObject:function(){var a=
-new n;return function(b){var c=this;b.updateMatrixWorld(!0);b.traverse(function(b){var e,f;e=b.geometry;if(void 0!==e)if(e.isGeometry){var g=e.vertices;e=0;for(f=g.length;e<f;e++)a.copy(g[e]),a.applyMatrix4(b.matrixWorld),c.expandByPoint(a)}else if(e.isBufferGeometry&&(g=e.attributes.position,void 0!==g))for(e=0,f=g.count;e<f;e++)a.fromBufferAttribute(g,e).applyMatrix4(b.matrixWorld),c.expandByPoint(a)});return this}}(),containsPoint:function(a){return a.x<this.min.x||a.x>this.max.x||a.y<this.min.y||
-a.y>this.max.y||a.z<this.min.z||a.z>this.max.z?!1:!0},containsBox:function(a){return this.min.x<=a.min.x&&a.max.x<=this.max.x&&this.min.y<=a.min.y&&a.max.y<=this.max.y&&this.min.z<=a.min.z&&a.max.z<=this.max.z},getParameter:function(a,b){return(b||new n).set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max.y-this.min.y),(a.z-this.min.z)/(this.max.z-this.min.z))},intersectsBox:function(a){return a.max.x<this.min.x||a.min.x>this.max.x||a.max.y<this.min.y||a.min.y>this.max.y||a.max.z<
-this.min.z||a.min.z>this.max.z?!1:!0},intersectsSphere:function(){var a=new n;return function(b){this.clampPoint(b.center,a);return a.distanceToSquared(b.center)<=b.radius*b.radius}}(),intersectsPlane:function(a){var b,c;0<a.normal.x?(b=a.normal.x*this.min.x,c=a.normal.x*this.max.x):(b=a.normal.x*this.max.x,c=a.normal.x*this.min.x);0<a.normal.y?(b+=a.normal.y*this.min.y,c+=a.normal.y*this.max.y):(b+=a.normal.y*this.max.y,c+=a.normal.y*this.min.y);0<a.normal.z?(b+=a.normal.z*this.min.z,c+=a.normal.z*
-this.max.z):(b+=a.normal.z*this.max.z,c+=a.normal.z*this.min.z);return b<=a.constant&&c>=a.constant},clampPoint:function(a,b){return(b||new n).copy(a).clamp(this.min,this.max)},distanceToPoint:function(){var a=new n;return function(b){return a.copy(b).clamp(this.min,this.max).sub(b).length()}}(),getBoundingSphere:function(){var a=new n;return function(b){b=b||new Ea;this.getCenter(b.center);b.radius=.5*this.getSize(a).length();return b}}(),intersect:function(a){this.min.max(a.min);this.max.min(a.max);
-this.isEmpty()&&this.makeEmpty();return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},applyMatrix4:function(){var a=[new n,new n,new n,new n,new n,new n,new n,new n];return function(b){if(this.isEmpty())return this;a[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(b);a[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(b);a[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(b);a[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(b);a[4].set(this.max.x,
-this.min.y,this.min.z).applyMatrix4(b);a[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(b);a[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(b);a[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(b);this.setFromPoints(a);return this}}(),translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)}});Object.assign(Ea.prototype,{set:function(a,b){this.center.copy(a);this.radius=b;return this},setFromPoints:function(){var a=
-new Ra;return function(b,c){var d=this.center;void 0!==c?d.copy(c):a.setFromPoints(b).getCenter(d);for(var e=0,f=0,g=b.length;f<g;f++)e=Math.max(e,d.distanceToSquared(b[f]));this.radius=Math.sqrt(e);return this}}(),clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.center.copy(a.center);this.radius=a.radius;return this},empty:function(){return 0>=this.radius},containsPoint:function(a){return a.distanceToSquared(this.center)<=this.radius*this.radius},distanceToPoint:function(a){return a.distanceTo(this.center)-
-this.radius},intersectsSphere:function(a){var b=this.radius+a.radius;return a.center.distanceToSquared(this.center)<=b*b},intersectsBox:function(a){return a.intersectsSphere(this)},intersectsPlane:function(a){return Math.abs(this.center.dot(a.normal)-a.constant)<=this.radius},clampPoint:function(a,b){var c=this.center.distanceToSquared(a),d=b||new n;d.copy(a);c>this.radius*this.radius&&(d.sub(this.center).normalize(),d.multiplyScalar(this.radius).add(this.center));return d},getBoundingBox:function(a){a=
-a||new Ra;a.set(this.center,this.center);a.expandByScalar(this.radius);return a},applyMatrix4:function(a){this.center.applyMatrix4(a);this.radius*=a.getMaxScaleOnAxis();return this},translate:function(a){this.center.add(a);return this},equals:function(a){return a.center.equals(this.center)&&a.radius===this.radius}});Object.assign(Ba.prototype,{isMatrix3:!0,set:function(a,b,c,d,e,f,g,h,k){var m=this.elements;m[0]=a;m[1]=d;m[2]=g;m[3]=b;m[4]=e;m[5]=h;m[6]=c;m[7]=f;m[8]=k;return this},identity:function(){this.set(1,
-0,0,0,1,0,0,0,1);return this},clone:function(){return(new this.constructor).fromArray(this.elements)},copy:function(a){var b=this.elements;a=a.elements;b[0]=a[0];b[1]=a[1];b[2]=a[2];b[3]=a[3];b[4]=a[4];b[5]=a[5];b[6]=a[6];b[7]=a[7];b[8]=a[8];return this},setFromMatrix4:function(a){a=a.elements;this.set(a[0],a[4],a[8],a[1],a[5],a[9],a[2],a[6],a[10]);return this},applyToBufferAttribute:function(){var a=new n;return function(b){for(var c=0,d=b.count;c<d;c++)a.x=b.getX(c),a.y=b.getY(c),a.z=b.getZ(c),
-a.applyMatrix3(this),b.setXYZ(c,a.x,a.y,a.z);return b}}(),multiply:function(a){return this.multiplyMatrices(this,a)},premultiply:function(a){return this.multiplyMatrices(a,this)},multiplyMatrices:function(a,b){var c=a.elements,d=b.elements,e=this.elements,f=c[0],g=c[3],h=c[6],k=c[1],m=c[4],q=c[7],l=c[2],p=c[5],c=c[8],r=d[0],n=d[3],t=d[6],y=d[1],x=d[4],u=d[7],H=d[2],w=d[5],d=d[8];e[0]=f*r+g*y+h*H;e[3]=f*n+g*x+h*w;e[6]=f*t+g*u+h*d;e[1]=k*r+m*y+q*H;e[4]=k*n+m*x+q*w;e[7]=k*t+m*u+q*d;e[2]=l*r+p*y+c*H;
-e[5]=l*n+p*x+c*w;e[8]=l*t+p*u+c*d;return this},multiplyScalar:function(a){var b=this.elements;b[0]*=a;b[3]*=a;b[6]*=a;b[1]*=a;b[4]*=a;b[7]*=a;b[2]*=a;b[5]*=a;b[8]*=a;return this},determinant:function(){var a=this.elements,b=a[0],c=a[1],d=a[2],e=a[3],f=a[4],g=a[5],h=a[6],k=a[7],a=a[8];return b*f*a-b*g*k-c*e*a+c*g*h+d*e*k-d*f*h},getInverse:function(a,b){a&&a.isMatrix4&&console.error("THREE.Matrix3.getInverse no longer takes a Matrix4 argument.");var c=a.elements,d=this.elements,e=c[0],f=c[1],g=c[2],
-h=c[3],k=c[4],m=c[5],q=c[6],l=c[7],c=c[8],p=c*k-m*l,r=m*q-c*h,n=l*h-k*q,t=e*p+f*r+g*n;if(0===t){if(!0===b)throw Error("THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0");console.warn("THREE.Matrix3.getInverse(): can't invert matrix, determinant is 0");return this.identity()}t=1/t;d[0]=p*t;d[1]=(g*l-c*f)*t;d[2]=(m*f-g*k)*t;d[3]=r*t;d[4]=(c*e-g*q)*t;d[5]=(g*h-m*e)*t;d[6]=n*t;d[7]=(f*q-l*e)*t;d[8]=(k*e-f*h)*t;return this},transpose:function(){var a,b=this.elements;a=b[1];b[1]=b[3];b[3]=
-a;a=b[2];b[2]=b[6];b[6]=a;a=b[5];b[5]=b[7];b[7]=a;return this},getNormalMatrix:function(a){return this.setFromMatrix4(a).getInverse(this).transpose()},transposeIntoArray:function(a){var b=this.elements;a[0]=b[0];a[1]=b[3];a[2]=b[6];a[3]=b[1];a[4]=b[4];a[5]=b[7];a[6]=b[2];a[7]=b[5];a[8]=b[8];return this},equals:function(a){var b=this.elements;a=a.elements;for(var c=0;9>c;c++)if(b[c]!==a[c])return!1;return!0},fromArray:function(a,b){void 0===b&&(b=0);for(var c=0;9>c;c++)this.elements[c]=a[c+b];return this},
-toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);var c=this.elements;a[b]=c[0];a[b+1]=c[1];a[b+2]=c[2];a[b+3]=c[3];a[b+4]=c[4];a[b+5]=c[5];a[b+6]=c[6];a[b+7]=c[7];a[b+8]=c[8];return a}});Object.assign(Aa.prototype,{set:function(a,b){this.normal.copy(a);this.constant=b;return this},setComponents:function(a,b,c,d){this.normal.set(a,b,c);this.constant=d;return this},setFromNormalAndCoplanarPoint:function(a,b){this.normal.copy(a);this.constant=-b.dot(this.normal);return this},setFromCoplanarPoints:function(){var a=
-new n,b=new n;return function(c,d,e){d=a.subVectors(e,d).cross(b.subVectors(c,d)).normalize();this.setFromNormalAndCoplanarPoint(d,c);return this}}(),clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.normal.copy(a.normal);this.constant=a.constant;return this},normalize:function(){var a=1/this.normal.length();this.normal.multiplyScalar(a);this.constant*=a;return this},negate:function(){this.constant*=-1;this.normal.negate();return this},distanceToPoint:function(a){return this.normal.dot(a)+
-this.constant},distanceToSphere:function(a){return this.distanceToPoint(a.center)-a.radius},projectPoint:function(a,b){return this.orthoPoint(a,b).sub(a).negate()},orthoPoint:function(a,b){var c=this.distanceToPoint(a);return(b||new n).copy(this.normal).multiplyScalar(c)},intersectLine:function(){var a=new n;return function(b,c){var d=c||new n,e=b.delta(a),f=this.normal.dot(e);if(0===f){if(0===this.distanceToPoint(b.start))return d.copy(b.start)}else return f=-(b.start.dot(this.normal)+this.constant)/
-f,0>f||1<f?void 0:d.copy(e).multiplyScalar(f).add(b.start)}}(),intersectsLine:function(a){var b=this.distanceToPoint(a.start);a=this.distanceToPoint(a.end);return 0>b&&0<a||0>a&&0<b},intersectsBox:function(a){return a.intersectsPlane(this)},intersectsSphere:function(a){return a.intersectsPlane(this)},coplanarPoint:function(a){return(a||new n).copy(this.normal).multiplyScalar(-this.constant)},applyMatrix4:function(){var a=new n,b=new Ba;return function(c,d){var e=this.coplanarPoint(a).applyMatrix4(c),
-f=d||b.getNormalMatrix(c),f=this.normal.applyMatrix3(f).normalize();this.constant=-e.dot(f);return this}}(),translate:function(a){this.constant-=a.dot(this.normal);return this},equals:function(a){return a.normal.equals(this.normal)&&a.constant===this.constant}});Object.assign(gd.prototype,{set:function(a,b,c,d,e,f){var g=this.planes;g[0].copy(a);g[1].copy(b);g[2].copy(c);g[3].copy(d);g[4].copy(e);g[5].copy(f);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){for(var b=
-this.planes,c=0;6>c;c++)b[c].copy(a.planes[c]);return this},setFromMatrix:function(a){var b=this.planes,c=a.elements;a=c[0];var d=c[1],e=c[2],f=c[3],g=c[4],h=c[5],k=c[6],m=c[7],q=c[8],l=c[9],p=c[10],r=c[11],n=c[12],t=c[13],y=c[14],c=c[15];b[0].setComponents(f-a,m-g,r-q,c-n).normalize();b[1].setComponents(f+a,m+g,r+q,c+n).normalize();b[2].setComponents(f+d,m+h,r+l,c+t).normalize();b[3].setComponents(f-d,m-h,r-l,c-t).normalize();b[4].setComponents(f-e,m-k,r-p,c-y).normalize();b[5].setComponents(f+e,
-m+k,r+p,c+y).normalize();return this},intersectsObject:function(){var a=new Ea;return function(b){var c=b.geometry;null===c.boundingSphere&&c.computeBoundingSphere();a.copy(c.boundingSphere).applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(),intersectsSprite:function(){var a=new Ea;return function(b){a.center.set(0,0,0);a.radius=.7071067811865476;a.applyMatrix4(b.matrixWorld);return this.intersectsSphere(a)}}(),intersectsSphere:function(a){var b=this.planes,c=a.center;a=-a.radius;for(var d=
-0;6>d;d++)if(b[d].distanceToPoint(c)<a)return!1;return!0},intersectsBox:function(){var a=new n,b=new n;return function(c){for(var d=this.planes,e=0;6>e;e++){var f=d[e];a.x=0<f.normal.x?c.min.x:c.max.x;b.x=0<f.normal.x?c.max.x:c.min.x;a.y=0<f.normal.y?c.min.y:c.max.y;b.y=0<f.normal.y?c.max.y:c.min.y;a.z=0<f.normal.z?c.min.z:c.max.z;b.z=0<f.normal.z?c.max.z:c.min.z;var g=f.distanceToPoint(a),f=f.distanceToPoint(b);if(0>g&&0>f)return!1}return!0}}(),containsPoint:function(a){for(var b=this.planes,c=0;6>
-c;c++)if(0>b[c].distanceToPoint(a))return!1;return!0}});ab.RotationOrders="XYZ YZX ZXY XZY YXZ ZYX".split(" ");ab.DefaultOrder="XYZ";Object.defineProperties(ab.prototype,{x:{get:function(){return this._x},set:function(a){this._x=a;this.onChangeCallback()}},y:{get:function(){return this._y},set:function(a){this._y=a;this.onChangeCallback()}},z:{get:function(){return this._z},set:function(a){this._z=a;this.onChangeCallback()}},order:{get:function(){return this._order},set:function(a){this._order=a;
-this.onChangeCallback()}}});Object.assign(ab.prototype,{isEuler:!0,set:function(a,b,c,d){this._x=a;this._y=b;this._z=c;this._order=d||this._order;this.onChangeCallback();return this},clone:function(){return new this.constructor(this._x,this._y,this._z,this._order)},copy:function(a){this._x=a._x;this._y=a._y;this._z=a._z;this._order=a._order;this.onChangeCallback();return this},setFromRotationMatrix:function(a,b,c){var d=Y.clamp,e=a.elements;a=e[0];var f=e[4],g=e[8],h=e[1],k=e[5],m=e[9],q=e[2],l=e[6],
-e=e[10];b=b||this._order;"XYZ"===b?(this._y=Math.asin(d(g,-1,1)),.99999>Math.abs(g)?(this._x=Math.atan2(-m,e),this._z=Math.atan2(-f,a)):(this._x=Math.atan2(l,k),this._z=0)):"YXZ"===b?(this._x=Math.asin(-d(m,-1,1)),.99999>Math.abs(m)?(this._y=Math.atan2(g,e),this._z=Math.atan2(h,k)):(this._y=Math.atan2(-q,a),this._z=0)):"ZXY"===b?(this._x=Math.asin(d(l,-1,1)),.99999>Math.abs(l)?(this._y=Math.atan2(-q,e),this._z=Math.atan2(-f,k)):(this._y=0,this._z=Math.atan2(h,a))):"ZYX"===b?(this._y=Math.asin(-d(q,
--1,1)),.99999>Math.abs(q)?(this._x=Math.atan2(l,e),this._z=Math.atan2(h,a)):(this._x=0,this._z=Math.atan2(-f,k))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.99999>Math.abs(h)?(this._x=Math.atan2(-m,k),this._y=Math.atan2(-q,a)):(this._x=0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z=Math.asin(-d(f,-1,1)),.99999>Math.abs(f)?(this._x=Math.atan2(l,k),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-m,e),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=
-b;if(!1!==c)this.onChangeCallback();return this},setFromQuaternion:function(){var a=new K;return function(b,c,d){a.makeRotationFromQuaternion(b);return this.setFromRotationMatrix(a,c,d)}}(),setFromVector3:function(a,b){return this.set(a.x,a.y,a.z,b||this._order)},reorder:function(){var a=new oa;return function(b){a.setFromEuler(this);return this.setFromQuaternion(a,b)}}(),equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},fromArray:function(a){this._x=
-a[0];this._y=a[1];this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._order;return a},toVector3:function(a){return a?a.set(this._x,this._y,this._z):new n(this._x,this._y,this._z)},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){}});Object.assign(Qd.prototype,{set:function(a){this.mask=1<<a|0},enable:function(a){this.mask=
-this.mask|1<<a|0},toggle:function(a){this.mask^=1<<a|0},disable:function(a){this.mask&=~(1<<a|0)},test:function(a){return 0!==(this.mask&a.mask)}});var Lf=0;z.DefaultUp=new n(0,1,0);z.DefaultMatrixAutoUpdate=!0;Object.assign(z.prototype,xa.prototype,{isObject3D:!0,onBeforeRender:function(){},onAfterRender:function(){},applyMatrix:function(a){this.matrix.multiplyMatrices(a,this.matrix);this.matrix.decompose(this.position,this.quaternion,this.scale)},applyQuaternion:function(a){this.quaternion.premultiply(a);
-return this},setRotationFromAxisAngle:function(a,b){this.quaternion.setFromAxisAngle(a,b)},setRotationFromEuler:function(a){this.quaternion.setFromEuler(a,!0)},setRotationFromMatrix:function(a){this.quaternion.setFromRotationMatrix(a)},setRotationFromQuaternion:function(a){this.quaternion.copy(a)},rotateOnAxis:function(){var a=new oa;return function(b,c){a.setFromAxisAngle(b,c);this.quaternion.multiply(a);return this}}(),rotateX:function(){var a=new n(1,0,0);return function(b){return this.rotateOnAxis(a,
-b)}}(),rotateY:function(){var a=new n(0,1,0);return function(b){return this.rotateOnAxis(a,b)}}(),rotateZ:function(){var a=new n(0,0,1);return function(b){return this.rotateOnAxis(a,b)}}(),translateOnAxis:function(){var a=new n;return function(b,c){a.copy(b).applyQuaternion(this.quaternion);this.position.add(a.multiplyScalar(c));return this}}(),translateX:function(){var a=new n(1,0,0);return function(b){return this.translateOnAxis(a,b)}}(),translateY:function(){var a=new n(0,1,0);return function(b){return this.translateOnAxis(a,
-b)}}(),translateZ:function(){var a=new n(0,0,1);return function(b){return this.translateOnAxis(a,b)}}(),localToWorld:function(a){return a.applyMatrix4(this.matrixWorld)},worldToLocal:function(){var a=new K;return function(b){return b.applyMatrix4(a.getInverse(this.matrixWorld))}}(),lookAt:function(){var a=new K;return function(b){this.isCamera?a.lookAt(this.position,b,this.up):a.lookAt(b,this.position,this.up);this.quaternion.setFromRotationMatrix(a)}}(),add:function(a){if(1<arguments.length){for(var b=
-0;b<arguments.length;b++)this.add(arguments[b]);return this}if(a===this)return console.error("THREE.Object3D.add: object can't be added as a child of itself.",a),this;a&&a.isObject3D?(null!==a.parent&&a.parent.remove(a),a.parent=this,a.dispatchEvent({type:"added"}),this.children.push(a)):console.error("THREE.Object3D.add: object not an instance of THREE.Object3D.",a);return this},remove:function(a){if(1<arguments.length){for(var b=0;b<arguments.length;b++)this.remove(arguments[b]);return this}b=this.children.indexOf(a);
--1!==b&&(a.parent=null,a.dispatchEvent({type:"removed"}),this.children.splice(b,1));return this},getObjectById:function(a){return this.getObjectByProperty("id",a)},getObjectByName:function(a){return this.getObjectByProperty("name",a)},getObjectByProperty:function(a,b){if(this[a]===b)return this;for(var c=0,d=this.children.length;c<d;c++){var e=this.children[c].getObjectByProperty(a,b);if(void 0!==e)return e}},getWorldPosition:function(a){a=a||new n;this.updateMatrixWorld(!0);return a.setFromMatrixPosition(this.matrixWorld)},
-getWorldQuaternion:function(){var a=new n,b=new n;return function(c){c=c||new oa;this.updateMatrixWorld(!0);this.matrixWorld.decompose(a,c,b);return c}}(),getWorldRotation:function(){var a=new oa;return function(b){b=b||new ab;this.getWorldQuaternion(a);return b.setFromQuaternion(a,this.rotation.order,!1)}}(),getWorldScale:function(){var a=new n,b=new oa;return function(c){c=c||new n;this.updateMatrixWorld(!0);this.matrixWorld.decompose(a,b,c);return c}}(),getWorldDirection:function(){var a=new oa;
-return function(b){b=b||new n;this.getWorldQuaternion(a);return b.set(0,0,1).applyQuaternion(a)}}(),raycast:function(){},traverse:function(a){a(this);for(var b=this.children,c=0,d=b.length;c<d;c++)b[c].traverse(a)},traverseVisible:function(a){if(!1!==this.visible){a(this);for(var b=this.children,c=0,d=b.length;c<d;c++)b[c].traverseVisible(a)}},traverseAncestors:function(a){var b=this.parent;null!==b&&(a(b),b.traverseAncestors(a))},updateMatrix:function(){this.matrix.compose(this.position,this.quaternion,
-this.scale);this.matrixWorldNeedsUpdate=!0},updateMatrixWorld:function(a){this.matrixAutoUpdate&&this.updateMatrix();if(this.matrixWorldNeedsUpdate||a)null===this.parent?this.matrixWorld.copy(this.matrix):this.matrixWorld.multiplyMatrices(this.parent.matrixWorld,this.matrix),this.matrixWorldNeedsUpdate=!1,a=!0;for(var b=this.children,c=0,d=b.length;c<d;c++)b[c].updateMatrixWorld(a)},toJSON:function(a){function b(b,c){void 0===b[c.uuid]&&(b[c.uuid]=c.toJSON(a));return c.uuid}function c(a){var b=[],
-c;for(c in a){var d=a[c];delete d.metadata;b.push(d)}return b}var d=void 0===a||""===a,e={};d&&(a={geometries:{},materials:{},textures:{},images:{}},e.metadata={version:4.5,type:"Object",generator:"Object3D.toJSON"});var f={};f.uuid=this.uuid;f.type=this.type;""!==this.name&&(f.name=this.name);"{}"!==JSON.stringify(this.userData)&&(f.userData=this.userData);!0===this.castShadow&&(f.castShadow=!0);!0===this.receiveShadow&&(f.receiveShadow=!0);!1===this.visible&&(f.visible=!1);f.matrix=this.matrix.toArray();
-void 0!==this.geometry&&(f.geometry=b(a.geometries,this.geometry));if(void 0!==this.material)if(Array.isArray(this.material)){for(var g=[],h=0,k=this.material.length;h<k;h++)g.push(b(a.materials,this.material[h]));f.material=g}else f.material=b(a.materials,this.material);if(0<this.children.length)for(f.children=[],h=0;h<this.children.length;h++)f.children.push(this.children[h].toJSON(a).object);d&&(d=c(a.geometries),g=c(a.materials),h=c(a.textures),k=c(a.images),0<d.length&&(e.geometries=d),0<g.length&&
-(e.materials=g),0<h.length&&(e.textures=h),0<k.length&&(e.images=k));e.object=f;return e},clone:function(a){return(new this.constructor).copy(this,a)},copy:function(a,b){void 0===b&&(b=!0);this.name=a.name;this.up.copy(a.up);this.position.copy(a.position);this.quaternion.copy(a.quaternion);this.scale.copy(a.scale);this.matrix.copy(a.matrix);this.matrixWorld.copy(a.matrixWorld);this.matrixAutoUpdate=a.matrixAutoUpdate;this.matrixWorldNeedsUpdate=a.matrixWorldNeedsUpdate;this.layers.mask=a.layers.mask;
-this.visible=a.visible;this.castShadow=a.castShadow;this.receiveShadow=a.receiveShadow;this.frustumCulled=a.frustumCulled;this.renderOrder=a.renderOrder;this.userData=JSON.parse(JSON.stringify(a.userData));if(!0===b)for(var c=0;c<a.children.length;c++)this.add(a.children[c].clone());return this}});Na.prototype=Object.assign(Object.create(z.prototype),{constructor:Na,isCamera:!0,copy:function(a,b){z.prototype.copy.call(this,a,b);this.matrixWorldInverse.copy(a.matrixWorldInverse);this.projectionMatrix.copy(a.projectionMatrix);
-return this},getWorldDirection:function(){var a=new oa;return function(b){b=b||new n;this.getWorldQuaternion(a);return b.set(0,0,-1).applyQuaternion(a)}}(),updateMatrixWorld:function(a){z.prototype.updateMatrixWorld.call(this,a);this.matrixWorldInverse.getInverse(this.matrixWorld)},clone:function(){return(new this.constructor).copy(this)}});Fb.prototype=Object.assign(Object.create(Na.prototype),{constructor:Fb,isOrthographicCamera:!0,copy:function(a,b){Na.prototype.copy.call(this,a,b);this.left=a.left;
-this.right=a.right;this.top=a.top;this.bottom=a.bottom;this.near=a.near;this.far=a.far;this.zoom=a.zoom;this.view=null===a.view?null:Object.assign({},a.view);return this},setViewOffset:function(a,b,c,d,e,f){this.view={fullWidth:a,fullHeight:b,offsetX:c,offsetY:d,width:e,height:f};this.updateProjectionMatrix()},clearViewOffset:function(){this.view=null;this.updateProjectionMatrix()},updateProjectionMatrix:function(){var a=(this.right-this.left)/(2*this.zoom),b=(this.top-this.bottom)/(2*this.zoom),
-c=(this.right+this.left)/2,d=(this.top+this.bottom)/2,e=c-a,c=c+a,a=d+b,b=d-b;if(null!==this.view)var c=this.zoom/(this.view.width/this.view.fullWidth),b=this.zoom/(this.view.height/this.view.fullHeight),f=(this.right-this.left)/this.view.width,d=(this.top-this.bottom)/this.view.height,e=e+this.view.offsetX/c*f,c=e+this.view.width/c*f,a=a-this.view.offsetY/b*d,b=a-this.view.height/b*d;this.projectionMatrix.makeOrthographic(e,c,a,b,this.near,this.far)},toJSON:function(a){a=z.prototype.toJSON.call(this,
-a);a.object.zoom=this.zoom;a.object.left=this.left;a.object.right=this.right;a.object.top=this.top;a.object.bottom=this.bottom;a.object.near=this.near;a.object.far=this.far;null!==this.view&&(a.object.view=Object.assign({},this.view));return a}});qa.prototype=Object.assign(Object.create(Na.prototype),{constructor:qa,isPerspectiveCamera:!0,copy:function(a,b){Na.prototype.copy.call(this,a,b);this.fov=a.fov;this.zoom=a.zoom;this.near=a.near;this.far=a.far;this.focus=a.focus;this.aspect=a.aspect;this.view=
-null===a.view?null:Object.assign({},a.view);this.filmGauge=a.filmGauge;this.filmOffset=a.filmOffset;return this},setFocalLength:function(a){a=.5*this.getFilmHeight()/a;this.fov=2*Y.RAD2DEG*Math.atan(a);this.updateProjectionMatrix()},getFocalLength:function(){var a=Math.tan(.5*Y.DEG2RAD*this.fov);return.5*this.getFilmHeight()/a},getEffectiveFOV:function(){return 2*Y.RAD2DEG*Math.atan(Math.tan(.5*Y.DEG2RAD*this.fov)/this.zoom)},getFilmWidth:function(){return this.filmGauge*Math.min(this.aspect,1)},
-getFilmHeight:function(){return this.filmGauge/Math.max(this.aspect,1)},setViewOffset:function(a,b,c,d,e,f){this.aspect=a/b;this.view={fullWidth:a,fullHeight:b,offsetX:c,offsetY:d,width:e,height:f};this.updateProjectionMatrix()},clearViewOffset:function(){this.view=null;this.updateProjectionMatrix()},updateProjectionMatrix:function(){var a=this.near,b=a*Math.tan(.5*Y.DEG2RAD*this.fov)/this.zoom,c=2*b,d=this.aspect*c,e=-.5*d,f=this.view;if(null!==f)var g=f.fullWidth,h=f.fullHeight,e=e+f.offsetX*d/
-g,b=b-f.offsetY*c/h,d=f.width/g*d,c=f.height/h*c;f=this.filmOffset;0!==f&&(e+=a*f/this.getFilmWidth());this.projectionMatrix.makePerspective(e,e+d,b,b-c,a,this.far)},toJSON:function(a){a=z.prototype.toJSON.call(this,a);a.object.fov=this.fov;a.object.zoom=this.zoom;a.object.near=this.near;a.object.far=this.far;a.object.focus=this.focus;a.object.aspect=this.aspect;null!==this.view&&(a.object.view=Object.assign({},this.view));a.object.filmGauge=this.filmGauge;a.object.filmOffset=this.filmOffset;return a}});
-Object.assign(Sa.prototype,{clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.a=a.a;this.b=a.b;this.c=a.c;this.normal.copy(a.normal);this.color.copy(a.color);this.materialIndex=a.materialIndex;for(var b=0,c=a.vertexNormals.length;b<c;b++)this.vertexNormals[b]=a.vertexNormals[b].clone();b=0;for(c=a.vertexColors.length;b<c;b++)this.vertexColors[b]=a.vertexColors[b].clone();return this}});var Rd=0;Object.assign(J.prototype,xa.prototype,{isGeometry:!0,applyMatrix:function(a){for(var b=
-(new Ba).getNormalMatrix(a),c=0,d=this.vertices.length;c<d;c++)this.vertices[c].applyMatrix4(a);c=0;for(d=this.faces.length;c<d;c++){a=this.faces[c];a.normal.applyMatrix3(b).normalize();for(var e=0,f=a.vertexNormals.length;e<f;e++)a.vertexNormals[e].applyMatrix3(b).normalize()}null!==this.boundingBox&&this.computeBoundingBox();null!==this.boundingSphere&&this.computeBoundingSphere();this.normalsNeedUpdate=this.verticesNeedUpdate=!0;return this},rotateX:function(){var a=new K;return function(b){a.makeRotationX(b);
-this.applyMatrix(a);return this}}(),rotateY:function(){var a=new K;return function(b){a.makeRotationY(b);this.applyMatrix(a);return this}}(),rotateZ:function(){var a=new K;return function(b){a.makeRotationZ(b);this.applyMatrix(a);return this}}(),translate:function(){var a=new K;return function(b,c,d){a.makeTranslation(b,c,d);this.applyMatrix(a);return this}}(),scale:function(){var a=new K;return function(b,c,d){a.makeScale(b,c,d);this.applyMatrix(a);return this}}(),lookAt:function(){var a=new z;return function(b){a.lookAt(b);
-a.updateMatrix();this.applyMatrix(a.matrix)}}(),fromBufferGeometry:function(a){function b(a,b,d,e){var f=void 0!==g?[q[a].clone(),q[b].clone(),q[d].clone()]:[],r=void 0!==h?[c.colors[a].clone(),c.colors[b].clone(),c.colors[d].clone()]:[];e=new Sa(a,b,d,f,r,e);c.faces.push(e);void 0!==k&&c.faceVertexUvs[0].push([l[a].clone(),l[b].clone(),l[d].clone()]);void 0!==m&&c.faceVertexUvs[1].push([p[a].clone(),p[b].clone(),p[d].clone()])}var c=this,d=null!==a.index?a.index.array:void 0,e=a.attributes,f=e.position.array,
-g=void 0!==e.normal?e.normal.array:void 0,h=void 0!==e.color?e.color.array:void 0,k=void 0!==e.uv?e.uv.array:void 0,m=void 0!==e.uv2?e.uv2.array:void 0;void 0!==m&&(this.faceVertexUvs[1]=[]);for(var q=[],l=[],p=[],r=e=0;e<f.length;e+=3,r+=2)c.vertices.push(new n(f[e],f[e+1],f[e+2])),void 0!==g&&q.push(new n(g[e],g[e+1],g[e+2])),void 0!==h&&c.colors.push(new G(h[e],h[e+1],h[e+2])),void 0!==k&&l.push(new C(k[r],k[r+1])),void 0!==m&&p.push(new C(m[r],m[r+1]));var ca=a.groups;if(0<ca.length)for(e=0;e<
-ca.length;e++)for(var f=ca[e],t=f.start,y=f.count,r=t,t=t+y;r<t;r+=3)void 0!==d?b(d[r],d[r+1],d[r+2],f.materialIndex):b(r,r+1,r+2,f.materialIndex);else if(void 0!==d)for(e=0;e<d.length;e+=3)b(d[e],d[e+1],d[e+2]);else for(e=0;e<f.length/3;e+=3)b(e,e+1,e+2);this.computeFaceNormals();null!==a.boundingBox&&(this.boundingBox=a.boundingBox.clone());null!==a.boundingSphere&&(this.boundingSphere=a.boundingSphere.clone());return this},center:function(){this.computeBoundingBox();var a=this.boundingBox.getCenter().negate();
-this.translate(a.x,a.y,a.z);return a},normalize:function(){this.computeBoundingSphere();var a=this.boundingSphere.center,b=this.boundingSphere.radius,b=0===b?1:1/b,c=new K;c.set(b,0,0,-b*a.x,0,b,0,-b*a.y,0,0,b,-b*a.z,0,0,0,1);this.applyMatrix(c);return this},computeFaceNormals:function(){for(var a=new n,b=new n,c=0,d=this.faces.length;c<d;c++){var e=this.faces[c],f=this.vertices[e.a],g=this.vertices[e.b];a.subVectors(this.vertices[e.c],g);b.subVectors(f,g);a.cross(b);a.normalize();e.normal.copy(a)}},
-computeVertexNormals:function(a){void 0===a&&(a=!0);var b,c,d;d=Array(this.vertices.length);b=0;for(c=this.vertices.length;b<c;b++)d[b]=new n;if(a){var e,f,g,h=new n,k=new n;a=0;for(b=this.faces.length;a<b;a++)c=this.faces[a],e=this.vertices[c.a],f=this.vertices[c.b],g=this.vertices[c.c],h.subVectors(g,f),k.subVectors(e,f),h.cross(k),d[c.a].add(h),d[c.b].add(h),d[c.c].add(h)}else for(this.computeFaceNormals(),a=0,b=this.faces.length;a<b;a++)c=this.faces[a],d[c.a].add(c.normal),d[c.b].add(c.normal),
-d[c.c].add(c.normal);b=0;for(c=this.vertices.length;b<c;b++)d[b].normalize();a=0;for(b=this.faces.length;a<b;a++)c=this.faces[a],e=c.vertexNormals,3===e.length?(e[0].copy(d[c.a]),e[1].copy(d[c.b]),e[2].copy(d[c.c])):(e[0]=d[c.a].clone(),e[1]=d[c.b].clone(),e[2]=d[c.c].clone());0<this.faces.length&&(this.normalsNeedUpdate=!0)},computeFlatVertexNormals:function(){var a,b,c;this.computeFaceNormals();a=0;for(b=this.faces.length;a<b;a++){c=this.faces[a];var d=c.vertexNormals;3===d.length?(d[0].copy(c.normal),
-d[1].copy(c.normal),d[2].copy(c.normal)):(d[0]=c.normal.clone(),d[1]=c.normal.clone(),d[2]=c.normal.clone())}0<this.faces.length&&(this.normalsNeedUpdate=!0)},computeMorphNormals:function(){var a,b,c,d,e;c=0;for(d=this.faces.length;c<d;c++)for(e=this.faces[c],e.__originalFaceNormal?e.__originalFaceNormal.copy(e.normal):e.__originalFaceNormal=e.normal.clone(),e.__originalVertexNormals||(e.__originalVertexNormals=[]),a=0,b=e.vertexNormals.length;a<b;a++)e.__originalVertexNormals[a]?e.__originalVertexNormals[a].copy(e.vertexNormals[a]):
-e.__originalVertexNormals[a]=e.vertexNormals[a].clone();var f=new J;f.faces=this.faces;a=0;for(b=this.morphTargets.length;a<b;a++){if(!this.morphNormals[a]){this.morphNormals[a]={};this.morphNormals[a].faceNormals=[];this.morphNormals[a].vertexNormals=[];e=this.morphNormals[a].faceNormals;var g=this.morphNormals[a].vertexNormals,h,k;c=0;for(d=this.faces.length;c<d;c++)h=new n,k={a:new n,b:new n,c:new n},e.push(h),g.push(k)}g=this.morphNormals[a];f.vertices=this.morphTargets[a].vertices;f.computeFaceNormals();
-f.computeVertexNormals();c=0;for(d=this.faces.length;c<d;c++)e=this.faces[c],h=g.faceNormals[c],k=g.vertexNormals[c],h.copy(e.normal),k.a.copy(e.vertexNormals[0]),k.b.copy(e.vertexNormals[1]),k.c.copy(e.vertexNormals[2])}c=0;for(d=this.faces.length;c<d;c++)e=this.faces[c],e.normal=e.__originalFaceNormal,e.vertexNormals=e.__originalVertexNormals},computeLineDistances:function(){for(var a=0,b=this.vertices,c=0,d=b.length;c<d;c++)0<c&&(a+=b[c].distanceTo(b[c-1])),this.lineDistances[c]=a},computeBoundingBox:function(){null===
-this.boundingBox&&(this.boundingBox=new Ra);this.boundingBox.setFromPoints(this.vertices)},computeBoundingSphere:function(){null===this.boundingSphere&&(this.boundingSphere=new Ea);this.boundingSphere.setFromPoints(this.vertices)},merge:function(a,b,c){if(a&&a.isGeometry){var d,e=this.vertices.length,f=this.vertices,g=a.vertices,h=this.faces,k=a.faces,m=this.faceVertexUvs[0],q=a.faceVertexUvs[0],l=this.colors,p=a.colors;void 0===c&&(c=0);void 0!==b&&(d=(new Ba).getNormalMatrix(b));a=0;for(var r=g.length;a<
-r;a++){var n=g[a].clone();void 0!==b&&n.applyMatrix4(b);f.push(n)}a=0;for(r=p.length;a<r;a++)l.push(p[a].clone());a=0;for(r=k.length;a<r;a++){var g=k[a],t=g.vertexNormals,p=g.vertexColors,l=new Sa(g.a+e,g.b+e,g.c+e);l.normal.copy(g.normal);void 0!==d&&l.normal.applyMatrix3(d).normalize();b=0;for(f=t.length;b<f;b++)n=t[b].clone(),void 0!==d&&n.applyMatrix3(d).normalize(),l.vertexNormals.push(n);l.color.copy(g.color);b=0;for(f=p.length;b<f;b++)n=p[b],l.vertexColors.push(n.clone());l.materialIndex=g.materialIndex+
-c;h.push(l)}a=0;for(r=q.length;a<r;a++)if(c=q[a],d=[],void 0!==c){b=0;for(f=c.length;b<f;b++)d.push(c[b].clone());m.push(d)}}else console.error("THREE.Geometry.merge(): geometry not an instance of THREE.Geometry.",a)},mergeMesh:function(a){a&&a.isMesh?(a.matrixAutoUpdate&&a.updateMatrix(),this.merge(a.geometry,a.matrix)):console.error("THREE.Geometry.mergeMesh(): mesh not an instance of THREE.Mesh.",a)},mergeVertices:function(){var a={},b=[],c=[],d,e=Math.pow(10,4),f,g;f=0;for(g=this.vertices.length;f<
-g;f++)d=this.vertices[f],d=Math.round(d.x*e)+"_"+Math.round(d.y*e)+"_"+Math.round(d.z*e),void 0===a[d]?(a[d]=f,b.push(this.vertices[f]),c[f]=b.length-1):c[f]=c[a[d]];a=[];f=0;for(g=this.faces.length;f<g;f++)for(e=this.faces[f],e.a=c[e.a],e.b=c[e.b],e.c=c[e.c],e=[e.a,e.b,e.c],d=0;3>d;d++)if(e[d]===e[(d+1)%3]){a.push(f);break}for(f=a.length-1;0<=f;f--)for(e=a[f],this.faces.splice(e,1),c=0,g=this.faceVertexUvs.length;c<g;c++)this.faceVertexUvs[c].splice(e,1);f=this.vertices.length-b.length;this.vertices=
-b;return f},sortFacesByMaterialIndex:function(){for(var a=this.faces,b=a.length,c=0;c<b;c++)a[c]._id=c;a.sort(function(a,b){return a.materialIndex-b.materialIndex});var d=this.faceVertexUvs[0],e=this.faceVertexUvs[1],f,g;d&&d.length===b&&(f=[]);e&&e.length===b&&(g=[]);for(c=0;c<b;c++){var h=a[c]._id;f&&f.push(d[h]);g&&g.push(e[h])}f&&(this.faceVertexUvs[0]=f);g&&(this.faceVertexUvs[1]=g)},toJSON:function(){function a(a,b,c){return c?a|1<<b:a&~(1<<b)}function b(a){var b=a.x.toString()+a.y.toString()+
-a.z.toString();if(void 0!==m[b])return m[b];m[b]=k.length/3;k.push(a.x,a.y,a.z);return m[b]}function c(a){var b=a.r.toString()+a.g.toString()+a.b.toString();if(void 0!==l[b])return l[b];l[b]=q.length;q.push(a.getHex());return l[b]}function d(a){var b=a.x.toString()+a.y.toString();if(void 0!==r[b])return r[b];r[b]=p.length/2;p.push(a.x,a.y);return r[b]}var e={metadata:{version:4.5,type:"Geometry",generator:"Geometry.toJSON"}};e.uuid=this.uuid;e.type=this.type;""!==this.name&&(e.name=this.name);if(void 0!==
-this.parameters){var f=this.parameters,g;for(g in f)void 0!==f[g]&&(e[g]=f[g]);return e}f=[];for(g=0;g<this.vertices.length;g++){var h=this.vertices[g];f.push(h.x,h.y,h.z)}var h=[],k=[],m={},q=[],l={},p=[],r={};for(g=0;g<this.faces.length;g++){var n=this.faces[g],t=void 0!==this.faceVertexUvs[0][g],y=0<n.normal.length(),x=0<n.vertexNormals.length,u=1!==n.color.r||1!==n.color.g||1!==n.color.b,H=0<n.vertexColors.length,w=0,w=a(w,0,0),w=a(w,1,!0),w=a(w,2,!1),w=a(w,3,t),w=a(w,4,y),w=a(w,5,x),w=a(w,6,
-u),w=a(w,7,H);h.push(w);h.push(n.a,n.b,n.c);h.push(n.materialIndex);t&&(t=this.faceVertexUvs[0][g],h.push(d(t[0]),d(t[1]),d(t[2])));y&&h.push(b(n.normal));x&&(y=n.vertexNormals,h.push(b(y[0]),b(y[1]),b(y[2])));u&&h.push(c(n.color));H&&(n=n.vertexColors,h.push(c(n[0]),c(n[1]),c(n[2])))}e.data={};e.data.vertices=f;e.data.normals=k;0<q.length&&(e.data.colors=q);0<p.length&&(e.data.uvs=[p]);e.data.faces=h;return e},clone:function(){return(new J).copy(this)},copy:function(a){var b,c,d,e,f,g;this.vertices=
-[];this.colors=[];this.faces=[];this.faceVertexUvs=[[]];this.morphTargets=[];this.morphNormals=[];this.skinWeights=[];this.skinIndices=[];this.lineDistances=[];this.boundingSphere=this.boundingBox=null;this.name=a.name;d=a.vertices;b=0;for(c=d.length;b<c;b++)this.vertices.push(d[b].clone());d=a.colors;b=0;for(c=d.length;b<c;b++)this.colors.push(d[b].clone());d=a.faces;b=0;for(c=d.length;b<c;b++)this.faces.push(d[b].clone());b=0;for(c=a.faceVertexUvs.length;b<c;b++){var h=a.faceVertexUvs[b];void 0===
-this.faceVertexUvs[b]&&(this.faceVertexUvs[b]=[]);d=0;for(e=h.length;d<e;d++){var k=h[d],m=[];f=0;for(g=k.length;f<g;f++)m.push(k[f].clone());this.faceVertexUvs[b].push(m)}}f=a.morphTargets;b=0;for(c=f.length;b<c;b++){g={};g.name=f[b].name;if(void 0!==f[b].vertices)for(g.vertices=[],d=0,e=f[b].vertices.length;d<e;d++)g.vertices.push(f[b].vertices[d].clone());if(void 0!==f[b].normals)for(g.normals=[],d=0,e=f[b].normals.length;d<e;d++)g.normals.push(f[b].normals[d].clone());this.morphTargets.push(g)}f=
-a.morphNormals;b=0;for(c=f.length;b<c;b++){g={};if(void 0!==f[b].vertexNormals)for(g.vertexNormals=[],d=0,e=f[b].vertexNormals.length;d<e;d++)h=f[b].vertexNormals[d],k={},k.a=h.a.clone(),k.b=h.b.clone(),k.c=h.c.clone(),g.vertexNormals.push(k);if(void 0!==f[b].faceNormals)for(g.faceNormals=[],d=0,e=f[b].faceNormals.length;d<e;d++)g.faceNormals.push(f[b].faceNormals[d].clone());this.morphNormals.push(g)}d=a.skinWeights;b=0;for(c=d.length;b<c;b++)this.skinWeights.push(d[b].clone());d=a.skinIndices;b=
-0;for(c=d.length;b<c;b++)this.skinIndices.push(d[b].clone());d=a.lineDistances;b=0;for(c=d.length;b<c;b++)this.lineDistances.push(d[b]);b=a.boundingBox;null!==b&&(this.boundingBox=b.clone());b=a.boundingSphere;null!==b&&(this.boundingSphere=b.clone());this.elementsNeedUpdate=a.elementsNeedUpdate;this.verticesNeedUpdate=a.verticesNeedUpdate;this.uvsNeedUpdate=a.uvsNeedUpdate;this.normalsNeedUpdate=a.normalsNeedUpdate;this.colorsNeedUpdate=a.colorsNeedUpdate;this.lineDistancesNeedUpdate=a.lineDistancesNeedUpdate;
-this.groupsNeedUpdate=a.groupsNeedUpdate;return this},dispose:function(){this.dispatchEvent({type:"dispose"})}});Object.defineProperty(Z.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.assign(Z.prototype,{isBufferAttribute:!0,setArray:function(a){if(Array.isArray(a))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.count=void 0!==a?a.length/this.itemSize:0;this.array=a},setDynamic:function(a){this.dynamic=a;return this},copy:function(a){this.array=
-new a.array.constructor(a.array);this.itemSize=a.itemSize;this.count=a.count;this.normalized=a.normalized;this.dynamic=a.dynamic;return this},copyAt:function(a,b,c){a*=this.itemSize;c*=b.itemSize;for(var d=0,e=this.itemSize;d<e;d++)this.array[a+d]=b.array[c+d];return this},copyArray:function(a){this.array.set(a);return this},copyColorsArray:function(a){for(var b=this.array,c=0,d=0,e=a.length;d<e;d++){var f=a[d];void 0===f&&(console.warn("THREE.BufferAttribute.copyColorsArray(): color is undefined",
-d),f=new G);b[c++]=f.r;b[c++]=f.g;b[c++]=f.b}return this},copyIndicesArray:function(a){for(var b=this.array,c=0,d=0,e=a.length;d<e;d++){var f=a[d];b[c++]=f.a;b[c++]=f.b;b[c++]=f.c}return this},copyVector2sArray:function(a){for(var b=this.array,c=0,d=0,e=a.length;d<e;d++){var f=a[d];void 0===f&&(console.warn("THREE.BufferAttribute.copyVector2sArray(): vector is undefined",d),f=new C);b[c++]=f.x;b[c++]=f.y}return this},copyVector3sArray:function(a){for(var b=this.array,c=0,d=0,e=a.length;d<e;d++){var f=
-a[d];void 0===f&&(console.warn("THREE.BufferAttribute.copyVector3sArray(): vector is undefined",d),f=new n);b[c++]=f.x;b[c++]=f.y;b[c++]=f.z}return this},copyVector4sArray:function(a){for(var b=this.array,c=0,d=0,e=a.length;d<e;d++){var f=a[d];void 0===f&&(console.warn("THREE.BufferAttribute.copyVector4sArray(): vector is undefined",d),f=new fa);b[c++]=f.x;b[c++]=f.y;b[c++]=f.z;b[c++]=f.w}return this},set:function(a,b){void 0===b&&(b=0);this.array.set(a,b);return this},getX:function(a){return this.array[a*
-this.itemSize]},setX:function(a,b){this.array[a*this.itemSize]=b;return this},getY:function(a){return this.array[a*this.itemSize+1]},setY:function(a,b){this.array[a*this.itemSize+1]=b;return this},getZ:function(a){return this.array[a*this.itemSize+2]},setZ:function(a,b){this.array[a*this.itemSize+2]=b;return this},getW:function(a){return this.array[a*this.itemSize+3]},setW:function(a,b){this.array[a*this.itemSize+3]=b;return this},setXY:function(a,b,c){a*=this.itemSize;this.array[a+0]=b;this.array[a+
-1]=c;return this},setXYZ:function(a,b,c,d){a*=this.itemSize;this.array[a+0]=b;this.array[a+1]=c;this.array[a+2]=d;return this},setXYZW:function(a,b,c,d,e){a*=this.itemSize;this.array[a+0]=b;this.array[a+1]=c;this.array[a+2]=d;this.array[a+3]=e;return this},onUpload:function(a){this.onUploadCallback=a;return this},clone:function(){return(new this.constructor(this.array,this.itemSize)).copy(this)}});pc.prototype=Object.create(Z.prototype);pc.prototype.constructor=pc;qc.prototype=Object.create(Z.prototype);
-qc.prototype.constructor=qc;rc.prototype=Object.create(Z.prototype);rc.prototype.constructor=rc;sc.prototype=Object.create(Z.prototype);sc.prototype.constructor=sc;gb.prototype=Object.create(Z.prototype);gb.prototype.constructor=gb;tc.prototype=Object.create(Z.prototype);tc.prototype.constructor=tc;hb.prototype=Object.create(Z.prototype);hb.prototype.constructor=hb;B.prototype=Object.create(Z.prototype);B.prototype.constructor=B;uc.prototype=Object.create(Z.prototype);uc.prototype.constructor=uc;
-Object.assign(Je.prototype,{computeGroups:function(a){var b,c=[],d=void 0;a=a.faces;for(var e=0;e<a.length;e++){var f=a[e];f.materialIndex!==d&&(d=f.materialIndex,void 0!==b&&(b.count=3*e-b.start,c.push(b)),b={start:3*e,materialIndex:d})}void 0!==b&&(b.count=3*e-b.start,c.push(b));this.groups=c},fromGeometry:function(a){var b=a.faces,c=a.vertices,d=a.faceVertexUvs,e=d[0]&&0<d[0].length,f=d[1]&&0<d[1].length,g=a.morphTargets,h=g.length,k;if(0<h){k=[];for(var m=0;m<h;m++)k[m]=[];this.morphTargets.position=
-k}var q=a.morphNormals,l=q.length,p;if(0<l){p=[];for(m=0;m<l;m++)p[m]=[];this.morphTargets.normal=p}for(var r=a.skinIndices,n=a.skinWeights,t=r.length===c.length,y=n.length===c.length,m=0;m<b.length;m++){var x=b[m];this.vertices.push(c[x.a],c[x.b],c[x.c]);var u=x.vertexNormals;3===u.length?this.normals.push(u[0],u[1],u[2]):(u=x.normal,this.normals.push(u,u,u));u=x.vertexColors;3===u.length?this.colors.push(u[0],u[1],u[2]):(u=x.color,this.colors.push(u,u,u));!0===e&&(u=d[0][m],void 0!==u?this.uvs.push(u[0],
-u[1],u[2]):(console.warn("THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ",m),this.uvs.push(new C,new C,new C)));!0===f&&(u=d[1][m],void 0!==u?this.uvs2.push(u[0],u[1],u[2]):(console.warn("THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ",m),this.uvs2.push(new C,new C,new C)));for(u=0;u<h;u++){var H=g[u].vertices;k[u].push(H[x.a],H[x.b],H[x.c])}for(u=0;u<l;u++)H=q[u].vertexNormals[m],p[u].push(H.a,H.b,H.c);t&&this.skinIndices.push(r[x.a],r[x.b],r[x.c]);y&&this.skinWeights.push(n[x.a],
-n[x.b],n[x.c])}this.computeGroups(a);this.verticesNeedUpdate=a.verticesNeedUpdate;this.normalsNeedUpdate=a.normalsNeedUpdate;this.colorsNeedUpdate=a.colorsNeedUpdate;this.uvsNeedUpdate=a.uvsNeedUpdate;this.groupsNeedUpdate=a.groupsNeedUpdate;return this}});E.MaxIndex=65535;Object.assign(E.prototype,xa.prototype,{isBufferGeometry:!0,getIndex:function(){return this.index},setIndex:function(a){Array.isArray(a)?this.index=new (65535<Sd(a)?hb:gb)(a,1):this.index=a},addAttribute:function(a,b,c){if(b&&b.isBufferAttribute||
-b&&b.isInterleavedBufferAttribute)if("index"===a)console.warn("THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute."),this.setIndex(b);else return this.attributes[a]=b,this;else console.warn("THREE.BufferGeometry: .addAttribute() now expects ( name, attribute )."),this.addAttribute(a,new Z(b,c))},getAttribute:function(a){return this.attributes[a]},removeAttribute:function(a){delete this.attributes[a];return this},addGroup:function(a,b,c){this.groups.push({start:a,count:b,materialIndex:void 0!==
-c?c:0})},clearGroups:function(){this.groups=[]},setDrawRange:function(a,b){this.drawRange.start=a;this.drawRange.count=b},applyMatrix:function(a){var b=this.attributes.position;void 0!==b&&(a.applyToBufferAttribute(b),b.needsUpdate=!0);b=this.attributes.normal;void 0!==b&&((new Ba).getNormalMatrix(a).applyToBufferAttribute(b),b.needsUpdate=!0);null!==this.boundingBox&&this.computeBoundingBox();null!==this.boundingSphere&&this.computeBoundingSphere();return this},rotateX:function(){var a=new K;return function(b){a.makeRotationX(b);
-this.applyMatrix(a);return this}}(),rotateY:function(){var a=new K;return function(b){a.makeRotationY(b);this.applyMatrix(a);return this}}(),rotateZ:function(){var a=new K;return function(b){a.makeRotationZ(b);this.applyMatrix(a);return this}}(),translate:function(){var a=new K;return function(b,c,d){a.makeTranslation(b,c,d);this.applyMatrix(a);return this}}(),scale:function(){var a=new K;return function(b,c,d){a.makeScale(b,c,d);this.applyMatrix(a);return this}}(),lookAt:function(){var a=new z;return function(b){a.lookAt(b);
-a.updateMatrix();this.applyMatrix(a.matrix)}}(),center:function(){this.computeBoundingBox();var a=this.boundingBox.getCenter().negate();this.translate(a.x,a.y,a.z);return a},setFromObject:function(a){var b=a.geometry;if(a.isPoints||a.isLine){a=new B(3*b.vertices.length,3);var c=new B(3*b.colors.length,3);this.addAttribute("position",a.copyVector3sArray(b.vertices));this.addAttribute("color",c.copyColorsArray(b.colors));b.lineDistances&&b.lineDistances.length===b.vertices.length&&(a=new B(b.lineDistances.length,
-1),this.addAttribute("lineDistance",a.copyArray(b.lineDistances)));null!==b.boundingSphere&&(this.boundingSphere=b.boundingSphere.clone());null!==b.boundingBox&&(this.boundingBox=b.boundingBox.clone())}else a.isMesh&&b&&b.isGeometry&&this.fromGeometry(b);return this},updateFromObject:function(a){var b=a.geometry;if(a.isMesh){var c=b.__directGeometry;!0===b.elementsNeedUpdate&&(c=void 0,b.elementsNeedUpdate=!1);if(void 0===c)return this.fromGeometry(b);c.verticesNeedUpdate=b.verticesNeedUpdate;c.normalsNeedUpdate=
-b.normalsNeedUpdate;c.colorsNeedUpdate=b.colorsNeedUpdate;c.uvsNeedUpdate=b.uvsNeedUpdate;c.groupsNeedUpdate=b.groupsNeedUpdate;b.verticesNeedUpdate=!1;b.normalsNeedUpdate=!1;b.colorsNeedUpdate=!1;b.uvsNeedUpdate=!1;b.groupsNeedUpdate=!1;b=c}!0===b.verticesNeedUpdate&&(c=this.attributes.position,void 0!==c&&(c.copyVector3sArray(b.vertices),c.needsUpdate=!0),b.verticesNeedUpdate=!1);!0===b.normalsNeedUpdate&&(c=this.attributes.normal,void 0!==c&&(c.copyVector3sArray(b.normals),c.needsUpdate=!0),b.normalsNeedUpdate=
-!1);!0===b.colorsNeedUpdate&&(c=this.attributes.color,void 0!==c&&(c.copyColorsArray(b.colors),c.needsUpdate=!0),b.colorsNeedUpdate=!1);b.uvsNeedUpdate&&(c=this.attributes.uv,void 0!==c&&(c.copyVector2sArray(b.uvs),c.needsUpdate=!0),b.uvsNeedUpdate=!1);b.lineDistancesNeedUpdate&&(c=this.attributes.lineDistance,void 0!==c&&(c.copyArray(b.lineDistances),c.needsUpdate=!0),b.lineDistancesNeedUpdate=!1);b.groupsNeedUpdate&&(b.computeGroups(a.geometry),this.groups=b.groups,b.groupsNeedUpdate=!1);return this},
-fromGeometry:function(a){a.__directGeometry=(new Je).fromGeometry(a);return this.fromDirectGeometry(a.__directGeometry)},fromDirectGeometry:function(a){var b=new Float32Array(3*a.vertices.length);this.addAttribute("position",(new Z(b,3)).copyVector3sArray(a.vertices));0<a.normals.length&&(b=new Float32Array(3*a.normals.length),this.addAttribute("normal",(new Z(b,3)).copyVector3sArray(a.normals)));0<a.colors.length&&(b=new Float32Array(3*a.colors.length),this.addAttribute("color",(new Z(b,3)).copyColorsArray(a.colors)));
-0<a.uvs.length&&(b=new Float32Array(2*a.uvs.length),this.addAttribute("uv",(new Z(b,2)).copyVector2sArray(a.uvs)));0<a.uvs2.length&&(b=new Float32Array(2*a.uvs2.length),this.addAttribute("uv2",(new Z(b,2)).copyVector2sArray(a.uvs2)));0<a.indices.length&&(b=new (65535<Sd(a.indices)?Uint32Array:Uint16Array)(3*a.indices.length),this.setIndex((new Z(b,1)).copyIndicesArray(a.indices)));this.groups=a.groups;for(var c in a.morphTargets){for(var b=[],d=a.morphTargets[c],e=0,f=d.length;e<f;e++){var g=d[e],
-h=new B(3*g.length,3);b.push(h.copyVector3sArray(g))}this.morphAttributes[c]=b}0<a.skinIndices.length&&(c=new B(4*a.skinIndices.length,4),this.addAttribute("skinIndex",c.copyVector4sArray(a.skinIndices)));0<a.skinWeights.length&&(c=new B(4*a.skinWeights.length,4),this.addAttribute("skinWeight",c.copyVector4sArray(a.skinWeights)));null!==a.boundingSphere&&(this.boundingSphere=a.boundingSphere.clone());null!==a.boundingBox&&(this.boundingBox=a.boundingBox.clone());return this},computeBoundingBox:function(){null===
-this.boundingBox&&(this.boundingBox=new Ra);var a=this.attributes.position;void 0!==a?this.boundingBox.setFromBufferAttribute(a):this.boundingBox.makeEmpty();(isNaN(this.boundingBox.min.x)||isNaN(this.boundingBox.min.y)||isNaN(this.boundingBox.min.z))&&console.error('THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.',this)},computeBoundingSphere:function(){var a=new Ra,b=new n;return function(){null===this.boundingSphere&&
-(this.boundingSphere=new Ea);var c=this.attributes.position;if(c){var d=this.boundingSphere.center;a.setFromBufferAttribute(c);a.getCenter(d);for(var e=0,f=0,g=c.count;f<g;f++)b.x=c.getX(f),b.y=c.getY(f),b.z=c.getZ(f),e=Math.max(e,d.distanceToSquared(b));this.boundingSphere.radius=Math.sqrt(e);isNaN(this.boundingSphere.radius)&&console.error('THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.',this)}}}(),computeFaceNormals:function(){},
-computeVertexNormals:function(){var a=this.index,b=this.attributes,c=this.groups;if(b.position){var d=b.position.array;if(void 0===b.normal)this.addAttribute("normal",new Z(new Float32Array(d.length),3));else for(var e=b.normal.array,f=0,g=e.length;f<g;f++)e[f]=0;var e=b.normal.array,h,k,m,q=new n,l=new n,p=new n,r=new n,ca=new n;if(a){a=a.array;0===c.length&&this.addGroup(0,a.length);for(var t=0,y=c.length;t<y;++t)for(f=c[t],g=f.start,h=f.count,f=g,g+=h;f<g;f+=3)h=3*a[f+0],k=3*a[f+1],m=3*a[f+2],
-q.fromArray(d,h),l.fromArray(d,k),p.fromArray(d,m),r.subVectors(p,l),ca.subVectors(q,l),r.cross(ca),e[h]+=r.x,e[h+1]+=r.y,e[h+2]+=r.z,e[k]+=r.x,e[k+1]+=r.y,e[k+2]+=r.z,e[m]+=r.x,e[m+1]+=r.y,e[m+2]+=r.z}else for(f=0,g=d.length;f<g;f+=9)q.fromArray(d,f),l.fromArray(d,f+3),p.fromArray(d,f+6),r.subVectors(p,l),ca.subVectors(q,l),r.cross(ca),e[f]=r.x,e[f+1]=r.y,e[f+2]=r.z,e[f+3]=r.x,e[f+4]=r.y,e[f+5]=r.z,e[f+6]=r.x,e[f+7]=r.y,e[f+8]=r.z;this.normalizeNormals();b.normal.needsUpdate=!0}},merge:function(a,
-b){if(a&&a.isBufferGeometry){void 0===b&&(b=0);var c=this.attributes,d;for(d in c)if(void 0!==a.attributes[d])for(var e=c[d].array,f=a.attributes[d],g=f.array,h=0,f=f.itemSize*b;h<g.length;h++,f++)e[f]=g[h];return this}console.error("THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.",a)},normalizeNormals:function(){for(var a=this.attributes.normal,b,c,d,e,f=0,g=a.count;f<g;f++)b=a.getX(f),c=a.getY(f),d=a.getZ(f),e=1/Math.sqrt(b*b+c*c+d*d),a.setXYZ(f,b*e,c*e,d*e)},toNonIndexed:function(){if(null===
-this.index)return console.warn("THREE.BufferGeometry.toNonIndexed(): Geometry is already non-indexed."),this;var a=new E,b=this.index.array,c=this.attributes,d;for(d in c){for(var e=c[d],f=e.array,e=e.itemSize,g=new f.constructor(b.length*e),h,k=0,m=0,q=b.length;m<q;m++){h=b[m]*e;for(var l=0;l<e;l++)g[k++]=f[h++]}a.addAttribute(d,new Z(g,e))}return a},toJSON:function(){var a={metadata:{version:4.5,type:"BufferGeometry",generator:"BufferGeometry.toJSON"}};a.uuid=this.uuid;a.type=this.type;""!==this.name&&
-(a.name=this.name);if(void 0!==this.parameters){var b=this.parameters,c;for(c in b)void 0!==b[c]&&(a[c]=b[c]);return a}a.data={attributes:{}};var d=this.index;null!==d&&(b=Array.prototype.slice.call(d.array),a.data.index={type:d.array.constructor.name,array:b});d=this.attributes;for(c in d){var e=d[c],b=Array.prototype.slice.call(e.array);a.data.attributes[c]={itemSize:e.itemSize,type:e.array.constructor.name,array:b,normalized:e.normalized}}c=this.groups;0<c.length&&(a.data.groups=JSON.parse(JSON.stringify(c)));
-c=this.boundingSphere;null!==c&&(a.data.boundingSphere={center:c.center.toArray(),radius:c.radius});return a},clone:function(){return(new E).copy(this)},copy:function(a){var b,c,d;this.index=null;this.attributes={};this.morphAttributes={};this.groups=[];this.boundingSphere=this.boundingBox=null;this.name=a.name;c=a.index;null!==c&&this.setIndex(c.clone());c=a.attributes;for(b in c)this.addAttribute(b,c[b].clone());var e=a.morphAttributes;for(b in e){var f=[],g=e[b];c=0;for(d=g.length;c<d;c++)f.push(g[c].clone());
-this.morphAttributes[b]=f}b=a.groups;c=0;for(d=b.length;c<d;c++)e=b[c],this.addGroup(e.start,e.count,e.materialIndex);b=a.boundingBox;null!==b&&(this.boundingBox=b.clone());b=a.boundingSphere;null!==b&&(this.boundingSphere=b.clone());this.drawRange.start=a.drawRange.start;this.drawRange.count=a.drawRange.count;return this},dispose:function(){this.dispatchEvent({type:"dispose"})}});Gb.prototype=Object.create(J.prototype);Gb.prototype.constructor=Gb;ib.prototype=Object.create(E.prototype);ib.prototype.constructor=
-ib;vc.prototype=Object.create(J.prototype);vc.prototype.constructor=vc;jb.prototype=Object.create(E.prototype);jb.prototype.constructor=jb;ya.prototype=Object.create(U.prototype);ya.prototype.constructor=ya;ya.prototype.isMeshBasicMaterial=!0;ya.prototype.copy=function(a){U.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.specularMap=a.specularMap;this.alphaMap=
-a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;return this};Object.assign(kb.prototype,{set:function(a,b){this.origin.copy(a);this.direction.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},
-copy:function(a){this.origin.copy(a.origin);this.direction.copy(a.direction);return this},at:function(a,b){return(b||new n).copy(this.direction).multiplyScalar(a).add(this.origin)},lookAt:function(a){this.direction.copy(a).sub(this.origin).normalize();return this},recast:function(){var a=new n;return function(b){this.origin.copy(this.at(b,a));return this}}(),closestPointToPoint:function(a,b){var c=b||new n;c.subVectors(a,this.origin);var d=c.dot(this.direction);return 0>d?c.copy(this.origin):c.copy(this.direction).multiplyScalar(d).add(this.origin)},
-distanceToPoint:function(a){return Math.sqrt(this.distanceSqToPoint(a))},distanceSqToPoint:function(){var a=new n;return function(b){var c=a.subVectors(b,this.origin).dot(this.direction);if(0>c)return this.origin.distanceToSquared(b);a.copy(this.direction).multiplyScalar(c).add(this.origin);return a.distanceToSquared(b)}}(),distanceSqToSegment:function(){var a=new n,b=new n,c=new n;return function(d,e,f,g){a.copy(d).add(e).multiplyScalar(.5);b.copy(e).sub(d).normalize();c.copy(this.origin).sub(a);
-var h=.5*d.distanceTo(e),k=-this.direction.dot(b),m=c.dot(this.direction),q=-c.dot(b),l=c.lengthSq(),p=Math.abs(1-k*k),r;0<p?(d=k*q-m,e=k*m-q,r=h*p,0<=d?e>=-r?e<=r?(h=1/p,d*=h,e*=h,k=d*(d+k*e+2*m)+e*(k*d+e+2*q)+l):(e=h,d=Math.max(0,-(k*e+m)),k=-d*d+e*(e+2*q)+l):(e=-h,d=Math.max(0,-(k*e+m)),k=-d*d+e*(e+2*q)+l):e<=-r?(d=Math.max(0,-(-k*h+m)),e=0<d?-h:Math.min(Math.max(-h,-q),h),k=-d*d+e*(e+2*q)+l):e<=r?(d=0,e=Math.min(Math.max(-h,-q),h),k=e*(e+2*q)+l):(d=Math.max(0,-(k*h+m)),e=0<d?h:Math.min(Math.max(-h,
--q),h),k=-d*d+e*(e+2*q)+l)):(e=0<k?-h:h,d=Math.max(0,-(k*e+m)),k=-d*d+e*(e+2*q)+l);f&&f.copy(this.direction).multiplyScalar(d).add(this.origin);g&&g.copy(b).multiplyScalar(e).add(a);return k}}(),intersectSphere:function(){var a=new n;return function(b,c){a.subVectors(b.center,this.origin);var d=a.dot(this.direction),e=a.dot(a)-d*d,f=b.radius*b.radius;if(e>f)return null;f=Math.sqrt(f-e);e=d-f;d+=f;return 0>e&&0>d?null:0>e?this.at(d,c):this.at(e,c)}}(),intersectsSphere:function(a){return this.distanceToPoint(a.center)<=
-a.radius},distanceToPlane:function(a){var b=a.normal.dot(this.direction);if(0===b)return 0===a.distanceToPoint(this.origin)?0:null;a=-(this.origin.dot(a.normal)+a.constant)/b;return 0<=a?a:null},intersectPlane:function(a,b){var c=this.distanceToPlane(a);return null===c?null:this.at(c,b)},intersectsPlane:function(a){var b=a.distanceToPoint(this.origin);return 0===b||0>a.normal.dot(this.direction)*b?!0:!1},intersectBox:function(a,b){var c,d,e,f,g;d=1/this.direction.x;f=1/this.direction.y;g=1/this.direction.z;
-var h=this.origin;0<=d?(c=(a.min.x-h.x)*d,d*=a.max.x-h.x):(c=(a.max.x-h.x)*d,d*=a.min.x-h.x);0<=f?(e=(a.min.y-h.y)*f,f*=a.max.y-h.y):(e=(a.max.y-h.y)*f,f*=a.min.y-h.y);if(c>f||e>d)return null;if(e>c||c!==c)c=e;if(f<d||d!==d)d=f;0<=g?(e=(a.min.z-h.z)*g,g*=a.max.z-h.z):(e=(a.max.z-h.z)*g,g*=a.min.z-h.z);if(c>g||e>d)return null;if(e>c||c!==c)c=e;if(g<d||d!==d)d=g;return 0>d?null:this.at(0<=c?c:d,b)},intersectsBox:function(){var a=new n;return function(b){return null!==this.intersectBox(b,a)}}(),intersectTriangle:function(){var a=
-new n,b=new n,c=new n,d=new n;return function(e,f,g,h,k){b.subVectors(f,e);c.subVectors(g,e);d.crossVectors(b,c);f=this.direction.dot(d);if(0<f){if(h)return null;h=1}else if(0>f)h=-1,f=-f;else return null;a.subVectors(this.origin,e);e=h*this.direction.dot(c.crossVectors(a,c));if(0>e)return null;g=h*this.direction.dot(b.cross(a));if(0>g||e+g>f)return null;e=-h*a.dot(d);return 0>e?null:this.at(e/f,k)}}(),applyMatrix4:function(a){this.origin.applyMatrix4(a);this.direction.transformDirection(a);return this},
-equals:function(a){return a.origin.equals(this.origin)&&a.direction.equals(this.direction)}});Object.assign(Hb.prototype,{set:function(a,b){this.start.copy(a);this.end.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.start.copy(a.start);this.end.copy(a.end);return this},getCenter:function(a){return(a||new n).addVectors(this.start,this.end).multiplyScalar(.5)},delta:function(a){return(a||new n).subVectors(this.end,this.start)},distanceSq:function(){return this.start.distanceToSquared(this.end)},
-distance:function(){return this.start.distanceTo(this.end)},at:function(a,b){var c=b||new n;return this.delta(c).multiplyScalar(a).add(this.start)},closestPointToPointParameter:function(){var a=new n,b=new n;return function(c,d){a.subVectors(c,this.start);b.subVectors(this.end,this.start);var e=b.dot(b),e=b.dot(a)/e;d&&(e=Y.clamp(e,0,1));return e}}(),closestPointToPoint:function(a,b,c){a=this.closestPointToPointParameter(a,b);c=c||new n;return this.delta(c).multiplyScalar(a).add(this.start)},applyMatrix4:function(a){this.start.applyMatrix4(a);
-this.end.applyMatrix4(a);return this},equals:function(a){return a.start.equals(this.start)&&a.end.equals(this.end)}});Object.assign(Ta,{normal:function(){var a=new n;return function(b,c,d,e){e=e||new n;e.subVectors(d,c);a.subVectors(b,c);e.cross(a);b=e.lengthSq();return 0<b?e.multiplyScalar(1/Math.sqrt(b)):e.set(0,0,0)}}(),barycoordFromPoint:function(){var a=new n,b=new n,c=new n;return function(d,e,f,g,h){a.subVectors(g,e);b.subVectors(f,e);c.subVectors(d,e);d=a.dot(a);e=a.dot(b);f=a.dot(c);var k=
-b.dot(b);g=b.dot(c);var m=d*k-e*e;h=h||new n;if(0===m)return h.set(-2,-1,-1);m=1/m;k=(k*f-e*g)*m;d=(d*g-e*f)*m;return h.set(1-k-d,d,k)}}(),containsPoint:function(){var a=new n;return function(b,c,d,e){b=Ta.barycoordFromPoint(b,c,d,e,a);return 0<=b.x&&0<=b.y&&1>=b.x+b.y}}()});Object.assign(Ta.prototype,{set:function(a,b,c){this.a.copy(a);this.b.copy(b);this.c.copy(c);return this},setFromPointsAndIndices:function(a,b,c,d){this.a.copy(a[b]);this.b.copy(a[c]);this.c.copy(a[d]);return this},clone:function(){return(new this.constructor).copy(this)},
-copy:function(a){this.a.copy(a.a);this.b.copy(a.b);this.c.copy(a.c);return this},area:function(){var a=new n,b=new n;return function(){a.subVectors(this.c,this.b);b.subVectors(this.a,this.b);return.5*a.cross(b).length()}}(),midpoint:function(a){return(a||new n).addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)},normal:function(a){return Ta.normal(this.a,this.b,this.c,a)},plane:function(a){return(a||new Aa).setFromCoplanarPoints(this.a,this.b,this.c)},barycoordFromPoint:function(a,b){return Ta.barycoordFromPoint(a,
-this.a,this.b,this.c,b)},containsPoint:function(a){return Ta.containsPoint(a,this.a,this.b,this.c)},closestPointToPoint:function(){var a=new Aa,b=[new Hb,new Hb,new Hb],c=new n,d=new n;return function(e,f){var g=f||new n,h=Infinity;a.setFromCoplanarPoints(this.a,this.b,this.c);a.projectPoint(e,c);if(!0===this.containsPoint(c))g.copy(c);else{b[0].set(this.a,this.b);b[1].set(this.b,this.c);b[2].set(this.c,this.a);for(var k=0;k<b.length;k++){b[k].closestPointToPoint(c,!0,d);var m=c.distanceToSquared(d);
-m<h&&(h=m,g.copy(d))}}return g}}(),equals:function(a){return a.a.equals(this.a)&&a.b.equals(this.b)&&a.c.equals(this.c)}});la.prototype=Object.assign(Object.create(z.prototype),{constructor:la,isMesh:!0,setDrawMode:function(a){this.drawMode=a},copy:function(a){z.prototype.copy.call(this,a);this.drawMode=a.drawMode;return this},updateMorphTargets:function(){var a=this.geometry,b,c;if(a.isBufferGeometry){if(a=a.morphAttributes,b=Object.keys(a),0<b.length){var d=a[b[0]];if(void 0!==d)for(this.morphTargetInfluences=
-[],this.morphTargetDictionary={},a=0,b=d.length;a<b;a++)c=d[a].name||String(a),this.morphTargetInfluences.push(0),this.morphTargetDictionary[c]=a}}else if(d=a.morphTargets,void 0!==d&&0<d.length)for(this.morphTargetInfluences=[],this.morphTargetDictionary={},a=0,b=d.length;a<b;a++)c=d[a].name||String(a),this.morphTargetInfluences.push(0),this.morphTargetDictionary[c]=a},raycast:function(){function a(a,b,c,d,e,f,g){Ta.barycoordFromPoint(a,b,c,d,t);e.multiplyScalar(t.x);f.multiplyScalar(t.y);g.multiplyScalar(t.z);
-e.add(f).add(g);return e.clone()}function b(a,b,c,d,e,f,g){var h=a.material;if(null===(1===h.side?c.intersectTriangle(f,e,d,!0,g):c.intersectTriangle(d,e,f,2!==h.side,g)))return null;x.copy(g);x.applyMatrix4(a.matrixWorld);c=b.ray.origin.distanceTo(x);return c<b.near||c>b.far?null:{distance:c,point:x.clone(),object:a}}function c(c,d,e,f,m,q,l,n){g.fromBufferAttribute(f,q);h.fromBufferAttribute(f,l);k.fromBufferAttribute(f,n);if(c=b(c,d,e,g,h,k,y))m&&(p.fromBufferAttribute(m,q),r.fromBufferAttribute(m,
-l),ca.fromBufferAttribute(m,n),c.uv=a(y,g,h,k,p,r,ca)),c.face=new Sa(q,l,n,Ta.normal(g,h,k)),c.faceIndex=q;return c}var d=new K,e=new kb,f=new Ea,g=new n,h=new n,k=new n,m=new n,q=new n,l=new n,p=new C,r=new C,ca=new C,t=new n,y=new n,x=new n;return function(n,t){var w=this.geometry,x=this.material,B=this.matrixWorld;if(void 0!==x&&(null===w.boundingSphere&&w.computeBoundingSphere(),f.copy(w.boundingSphere),f.applyMatrix4(B),!1!==n.ray.intersectsSphere(f)&&(d.getInverse(B),e.copy(n.ray).applyMatrix4(d),
-null===w.boundingBox||!1!==e.intersectsBox(w.boundingBox)))){var D;if(w.isBufferGeometry){var O,C,x=w.index,F=w.attributes.position,B=w.attributes.uv,z,T;if(null!==x)for(z=0,T=x.count;z<T;z+=3){if(w=x.getX(z),O=x.getX(z+1),C=x.getX(z+2),D=c(this,n,e,F,B,w,O,C))D.faceIndex=Math.floor(z/3),t.push(D)}else for(z=0,T=F.count;z<T;z+=3)if(w=z,O=z+1,C=z+2,D=c(this,n,e,F,B,w,O,C))D.index=w,t.push(D)}else if(w.isGeometry){var E,B=Array.isArray(x);z=w.vertices;T=w.faces;O=w.faceVertexUvs[0];0<O.length&&(F=O);
-for(var G=0,K=T.length;G<K;G++){var P=T[G];D=B?x[P.materialIndex]:x;if(void 0!==D){O=z[P.a];C=z[P.b];E=z[P.c];if(!0===D.morphTargets){D=w.morphTargets;var M=this.morphTargetInfluences;g.set(0,0,0);h.set(0,0,0);k.set(0,0,0);for(var V=0,pa=D.length;V<pa;V++){var S=M[V];if(0!==S){var N=D[V].vertices;g.addScaledVector(m.subVectors(N[P.a],O),S);h.addScaledVector(q.subVectors(N[P.b],C),S);k.addScaledVector(l.subVectors(N[P.c],E),S)}}g.add(O);h.add(C);k.add(E);O=g;C=h;E=k}if(D=b(this,n,e,O,C,E,y))F&&F[G]&&
-(M=F[G],p.copy(M[0]),r.copy(M[1]),ca.copy(M[2]),D.uv=a(y,O,C,E,p,r,ca)),D.face=P,D.faceIndex=G,t.push(D)}}}}}}(),clone:function(){return(new this.constructor(this.geometry,this.material)).copy(this)}});var bg=0;kd.prototype=Object.assign(Object.create(qa.prototype),{constructor:kd,isArrayCamera:!0});Ib.prototype.isFogExp2=!0;Ib.prototype.clone=function(){return new Ib(this.color.getHex(),this.density)};Ib.prototype.toJSON=function(a){return{type:"FogExp2",color:this.color.getHex(),density:this.density}};
-Jb.prototype.isFog=!0;Jb.prototype.clone=function(){return new Jb(this.color.getHex(),this.near,this.far)};Jb.prototype.toJSON=function(a){return{type:"Fog",color:this.color.getHex(),near:this.near,far:this.far}};ld.prototype=Object.assign(Object.create(z.prototype),{constructor:ld,copy:function(a,b){z.prototype.copy.call(this,a,b);null!==a.background&&(this.background=a.background.clone());null!==a.fog&&(this.fog=a.fog.clone());null!==a.overrideMaterial&&(this.overrideMaterial=a.overrideMaterial.clone());
-this.autoUpdate=a.autoUpdate;this.matrixAutoUpdate=a.matrixAutoUpdate;return this},toJSON:function(a){var b=z.prototype.toJSON.call(this,a);null!==this.background&&(b.object.background=this.background.toJSON(a));null!==this.fog&&(b.object.fog=this.fog.toJSON());return b}});Yd.prototype=Object.assign(Object.create(z.prototype),{constructor:Yd,isLensFlare:!0,copy:function(a){z.prototype.copy.call(this,a);this.positionScreen.copy(a.positionScreen);this.customUpdateCallback=a.customUpdateCallback;for(var b=
-0,c=a.lensFlares.length;b<c;b++)this.lensFlares.push(a.lensFlares[b]);return this},add:function(a,b,c,d,e,f){void 0===b&&(b=-1);void 0===c&&(c=0);void 0===f&&(f=1);void 0===e&&(e=new G(16777215));void 0===d&&(d=1);c=Math.min(c,Math.max(0,c));this.lensFlares.push({texture:a,size:b,distance:c,x:0,y:0,z:0,scale:1,rotation:0,opacity:f,color:e,blending:d})},updateLensFlares:function(){var a,b=this.lensFlares.length,c,d=2*-this.positionScreen.x,e=2*-this.positionScreen.y;for(a=0;a<b;a++)c=this.lensFlares[a],
-c.x=this.positionScreen.x+d*c.distance,c.y=this.positionScreen.y+e*c.distance,c.wantedRotation=c.x*Math.PI*.25,c.rotation+=.25*(c.wantedRotation-c.rotation)}});bb.prototype=Object.create(U.prototype);bb.prototype.constructor=bb;bb.prototype.isSpriteMaterial=!0;bb.prototype.copy=function(a){U.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.rotation=a.rotation;return this};xc.prototype=Object.assign(Object.create(z.prototype),{constructor:xc,isSprite:!0,raycast:function(){var a=
-new n,b=new n,c=new n;return function(d,e){b.setFromMatrixPosition(this.matrixWorld);d.ray.closestPointToPoint(b,a);c.setFromMatrixScale(this.matrixWorld);var f=c.x*c.y/4;b.distanceToSquared(a)>f||(f=d.ray.origin.distanceTo(a),f<d.near||f>d.far||e.push({distance:f,point:a.clone(),face:null,object:this}))}}(),clone:function(){return(new this.constructor(this.material)).copy(this)}});yc.prototype=Object.assign(Object.create(z.prototype),{constructor:yc,copy:function(a){z.prototype.copy.call(this,a,
-!1);a=a.levels;for(var b=0,c=a.length;b<c;b++){var d=a[b];this.addLevel(d.object.clone(),d.distance)}return this},addLevel:function(a,b){void 0===b&&(b=0);b=Math.abs(b);for(var c=this.levels,d=0;d<c.length&&!(b<c[d].distance);d++);c.splice(d,0,{distance:b,object:a});this.add(a)},getObjectForDistance:function(a){for(var b=this.levels,c=1,d=b.length;c<d&&!(a<b[c].distance);c++);return b[c-1].object},raycast:function(){var a=new n;return function(b,c){a.setFromMatrixPosition(this.matrixWorld);var d=
-b.ray.origin.distanceTo(a);this.getObjectForDistance(d).raycast(b,c)}}(),update:function(){var a=new n,b=new n;return function(c){var d=this.levels;if(1<d.length){a.setFromMatrixPosition(c.matrixWorld);b.setFromMatrixPosition(this.matrixWorld);c=a.distanceTo(b);d[0].object.visible=!0;for(var e=1,f=d.length;e<f;e++)if(c>=d[e].distance)d[e-1].object.visible=!1,d[e].object.visible=!0;else break;for(;e<f;e++)d[e].object.visible=!1}}}(),toJSON:function(a){a=z.prototype.toJSON.call(this,a);a.object.levels=
-[];for(var b=this.levels,c=0,d=b.length;c<d;c++){var e=b[c];a.object.levels.push({object:e.object.uuid,distance:e.distance})}return a}});Object.assign(zc.prototype,{calculateInverses:function(){this.boneInverses=[];for(var a=0,b=this.bones.length;a<b;a++){var c=new K;this.bones[a]&&c.getInverse(this.bones[a].matrixWorld);this.boneInverses.push(c)}},pose:function(){var a,b,c;b=0;for(c=this.bones.length;b<c;b++)(a=this.bones[b])&&a.matrixWorld.getInverse(this.boneInverses[b]);b=0;for(c=this.bones.length;b<
-c;b++)if(a=this.bones[b])a.parent&&a.parent.isBone?(a.matrix.getInverse(a.parent.matrixWorld),a.matrix.multiply(a.matrixWorld)):a.matrix.copy(a.matrixWorld),a.matrix.decompose(a.position,a.quaternion,a.scale)},update:function(){var a=new K,b=new K;return function(){for(var c=this.bones,d=this.boneInverses,e=this.boneMatrices,f=this.boneTexture,g=0,h=c.length;g<h;g++)a.multiplyMatrices(c[g]?c[g].matrixWorld:b,d[g]),a.toArray(e,16*g);void 0!==f&&(f.needsUpdate=!0)}}(),clone:function(){return new zc(this.bones,
-this.boneInverses)}});md.prototype=Object.assign(Object.create(z.prototype),{constructor:md,isBone:!0});nd.prototype=Object.assign(Object.create(la.prototype),{constructor:nd,isSkinnedMesh:!0,initBones:function(){var a=[],b,c,d,e;if(this.geometry&&void 0!==this.geometry.bones){d=0;for(e=this.geometry.bones.length;d<e;d++)c=this.geometry.bones[d],b=new md,a.push(b),b.name=c.name,b.position.fromArray(c.pos),b.quaternion.fromArray(c.rotq),void 0!==c.scl&&b.scale.fromArray(c.scl);d=0;for(e=this.geometry.bones.length;d<
-e;d++)c=this.geometry.bones[d],-1!==c.parent&&null!==c.parent&&void 0!==a[c.parent]?a[c.parent].add(a[d]):this.add(a[d])}this.updateMatrixWorld(!0);return a},bind:function(a,b){this.skeleton=a;void 0===b&&(this.updateMatrixWorld(!0),this.skeleton.calculateInverses(),b=this.matrixWorld);this.bindMatrix.copy(b);this.bindMatrixInverse.getInverse(b)},pose:function(){this.skeleton.pose()},normalizeSkinWeights:function(){var a,b;if(this.geometry&&this.geometry.isGeometry)for(b=0;b<this.geometry.skinWeights.length;b++){var c=
-this.geometry.skinWeights[b];a=1/c.lengthManhattan();Infinity!==a?c.multiplyScalar(a):c.set(1,0,0,0)}else if(this.geometry&&this.geometry.isBufferGeometry){var c=new fa,d=this.geometry.attributes.skinWeight;for(b=0;b<d.count;b++)c.x=d.getX(b),c.y=d.getY(b),c.z=d.getZ(b),c.w=d.getW(b),a=1/c.lengthManhattan(),Infinity!==a?c.multiplyScalar(a):c.set(1,0,0,0),d.setXYZW(b,c.x,c.y,c.z,c.w)}},updateMatrixWorld:function(a){la.prototype.updateMatrixWorld.call(this,a);"attached"===this.bindMode?this.bindMatrixInverse.getInverse(this.matrixWorld):
-"detached"===this.bindMode?this.bindMatrixInverse.getInverse(this.bindMatrix):console.warn("THREE.SkinnedMesh: Unrecognized bindMode: "+this.bindMode)},clone:function(){return(new this.constructor(this.geometry,this.material)).copy(this)}});ea.prototype=Object.create(U.prototype);ea.prototype.constructor=ea;ea.prototype.isLineBasicMaterial=!0;ea.prototype.copy=function(a){U.prototype.copy.call(this,a);this.color.copy(a.color);this.linewidth=a.linewidth;this.linecap=a.linecap;this.linejoin=a.linejoin;
-return this};sa.prototype=Object.assign(Object.create(z.prototype),{constructor:sa,isLine:!0,raycast:function(){var a=new K,b=new kb,c=new Ea;return function(d,e){var f=d.linePrecision,f=f*f,g=this.geometry,h=this.matrixWorld;null===g.boundingSphere&&g.computeBoundingSphere();c.copy(g.boundingSphere);c.applyMatrix4(h);if(!1!==d.ray.intersectsSphere(c)){a.getInverse(h);b.copy(d.ray).applyMatrix4(a);var k=new n,m=new n,h=new n,q=new n,l=this&&this.isLineSegments?2:1;if(g.isBufferGeometry){var p=g.index,
-r=g.attributes.position.array;if(null!==p)for(var p=p.array,g=0,ca=p.length-1;g<ca;g+=l){var t=p[g+1];k.fromArray(r,3*p[g]);m.fromArray(r,3*t);t=b.distanceSqToSegment(k,m,q,h);t>f||(q.applyMatrix4(this.matrixWorld),t=d.ray.origin.distanceTo(q),t<d.near||t>d.far||e.push({distance:t,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else for(g=0,ca=r.length/3-1;g<ca;g+=l)k.fromArray(r,3*g),m.fromArray(r,3*g+3),t=b.distanceSqToSegment(k,m,q,h),t>f||(q.applyMatrix4(this.matrixWorld),
-t=d.ray.origin.distanceTo(q),t<d.near||t>d.far||e.push({distance:t,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g.isGeometry)for(k=g.vertices,m=k.length,g=0;g<m-1;g+=l)t=b.distanceSqToSegment(k[g],k[g+1],q,h),t>f||(q.applyMatrix4(this.matrixWorld),t=d.ray.origin.distanceTo(q),t<d.near||t>d.far||e.push({distance:t,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}}}(),clone:function(){return(new this.constructor(this.geometry,
-this.material)).copy(this)}});Q.prototype=Object.assign(Object.create(sa.prototype),{constructor:Q,isLineSegments:!0});od.prototype=Object.assign(Object.create(sa.prototype),{constructor:od,isLineLoop:!0});Fa.prototype=Object.create(U.prototype);Fa.prototype.constructor=Fa;Fa.prototype.isPointsMaterial=!0;Fa.prototype.copy=function(a){U.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.size=a.size;this.sizeAttenuation=a.sizeAttenuation;return this};Kb.prototype=Object.assign(Object.create(z.prototype),
-{constructor:Kb,isPoints:!0,raycast:function(){var a=new K,b=new kb,c=new Ea;return function(d,e){function f(a,c){var f=b.distanceSqToPoint(a);if(f<q){var h=b.closestPointToPoint(a);h.applyMatrix4(k);var m=d.ray.origin.distanceTo(h);m<d.near||m>d.far||e.push({distance:m,distanceToRay:Math.sqrt(f),point:h.clone(),index:c,face:null,object:g})}}var g=this,h=this.geometry,k=this.matrixWorld,m=d.params.Points.threshold;null===h.boundingSphere&&h.computeBoundingSphere();c.copy(h.boundingSphere);c.applyMatrix4(k);
-c.radius+=m;if(!1!==d.ray.intersectsSphere(c)){a.getInverse(k);b.copy(d.ray).applyMatrix4(a);var m=m/((this.scale.x+this.scale.y+this.scale.z)/3),q=m*m,m=new n;if(h.isBufferGeometry){var l=h.index,h=h.attributes.position.array;if(null!==l)for(var p=l.array,l=0,r=p.length;l<r;l++){var ca=p[l];m.fromArray(h,3*ca);f(m,ca)}else for(l=0,p=h.length/3;l<p;l++)m.fromArray(h,3*l),f(m,l)}else for(m=h.vertices,l=0,p=m.length;l<p;l++)f(m[l],l)}}}(),clone:function(){return(new this.constructor(this.geometry,this.material)).copy(this)}});
-Ac.prototype=Object.assign(Object.create(z.prototype),{constructor:Ac});pd.prototype=Object.create(ba.prototype);pd.prototype.constructor=pd;Lb.prototype=Object.create(ba.prototype);Lb.prototype.constructor=Lb;Lb.prototype.isCompressedTexture=!0;qd.prototype=Object.create(ba.prototype);qd.prototype.constructor=qd;Bc.prototype=Object.create(ba.prototype);Bc.prototype.constructor=Bc;Bc.prototype.isDepthTexture=!0;Mb.prototype=Object.create(E.prototype);Mb.prototype.constructor=Mb;Cc.prototype=Object.create(J.prototype);
-Cc.prototype.constructor=Cc;Nb.prototype=Object.create(E.prototype);Nb.prototype.constructor=Nb;Dc.prototype=Object.create(J.prototype);Dc.prototype.constructor=Dc;za.prototype=Object.create(E.prototype);za.prototype.constructor=za;Ec.prototype=Object.create(J.prototype);Ec.prototype.constructor=Ec;Ob.prototype=Object.create(za.prototype);Ob.prototype.constructor=Ob;Fc.prototype=Object.create(J.prototype);Fc.prototype.constructor=Fc;lb.prototype=Object.create(za.prototype);lb.prototype.constructor=
-lb;Gc.prototype=Object.create(J.prototype);Gc.prototype.constructor=Gc;Pb.prototype=Object.create(za.prototype);Pb.prototype.constructor=Pb;Hc.prototype=Object.create(J.prototype);Hc.prototype.constructor=Hc;Qb.prototype=Object.create(za.prototype);Qb.prototype.constructor=Qb;Ic.prototype=Object.create(J.prototype);Ic.prototype.constructor=Ic;Rb.prototype=Object.create(E.prototype);Rb.prototype.constructor=Rb;Jc.prototype=Object.create(J.prototype);Jc.prototype.constructor=Jc;Sb.prototype=Object.create(E.prototype);
-Sb.prototype.constructor=Sb;Kc.prototype=Object.create(J.prototype);Kc.prototype.constructor=Kc;Tb.prototype=Object.create(E.prototype);Tb.prototype.constructor=Tb;var Ia={area:function(a){for(var b=a.length,c=0,d=b-1,e=0;e<b;d=e++)c+=a[d].x*a[e].y-a[e].x*a[d].y;return.5*c},triangulate:function(){return function(a,b){var c=a.length;if(3>c)return null;var d=[],e=[],f=[],g,h,k;if(0<Ia.area(a))for(h=0;h<c;h++)e[h]=h;else for(h=0;h<c;h++)e[h]=c-1-h;var m=2*c;for(h=c-1;2<c;){if(0>=m--){console.warn("THREE.ShapeUtils: Unable to triangulate polygon! in triangulate()");
-break}g=h;c<=g&&(g=0);h=g+1;c<=h&&(h=0);k=h+1;c<=k&&(k=0);var q;a:{var l,p,r,n,t,y,x,u;l=a[e[g]].x;p=a[e[g]].y;r=a[e[h]].x;n=a[e[h]].y;t=a[e[k]].x;y=a[e[k]].y;if(0>=(r-l)*(y-p)-(n-p)*(t-l))q=!1;else{var H,w,I,z,D,O,B,C,E,G;H=t-r;w=y-n;I=l-t;z=p-y;D=r-l;O=n-p;for(q=0;q<c;q++)if(x=a[e[q]].x,u=a[e[q]].y,!(x===l&&u===p||x===r&&u===n||x===t&&u===y)&&(B=x-l,C=u-p,E=x-r,G=u-n,x-=t,u-=y,E=H*G-w*E,B=D*C-O*B,C=I*u-z*x,E>=-Number.EPSILON&&C>=-Number.EPSILON&&B>=-Number.EPSILON)){q=!1;break a}q=!0}}if(q){d.push([a[e[g]],
-a[e[h]],a[e[k]]]);f.push([e[g],e[h],e[k]]);g=h;for(k=h+1;k<c;g++,k++)e[g]=e[k];c--;m=2*c}}return b?f:d}}(),triangulateShape:function(a,b){function c(a){var b=a.length;2<b&&a[b-1].equals(a[0])&&a.pop()}function d(a,b,c){return a.x!==b.x?a.x<b.x?a.x<=c.x&&c.x<=b.x:b.x<=c.x&&c.x<=a.x:a.y<b.y?a.y<=c.y&&c.y<=b.y:b.y<=c.y&&c.y<=a.y}function e(a,b,c,e,f){var g=b.x-a.x,h=b.y-a.y,k=e.x-c.x,m=e.y-c.y,q=a.x-c.x,l=a.y-c.y,p=h*k-g*m,n=h*q-g*l;if(Math.abs(p)>Number.EPSILON){if(0<p){if(0>n||n>p)return[];k=m*q-k*
-l;if(0>k||k>p)return[]}else{if(0<n||n<p)return[];k=m*q-k*l;if(0<k||k<p)return[]}if(0===k)return!f||0!==n&&n!==p?[a]:[];if(k===p)return!f||0!==n&&n!==p?[b]:[];if(0===n)return[c];if(n===p)return[e];f=k/p;return[{x:a.x+f*g,y:a.y+f*h}]}if(0!==n||m*q!==k*l)return[];h=0===g&&0===h;k=0===k&&0===m;if(h&&k)return a.x!==c.x||a.y!==c.y?[]:[a];if(h)return d(c,e,a)?[a]:[];if(k)return d(a,b,c)?[c]:[];0!==g?(a.x<b.x?(g=a,k=a.x,h=b,a=b.x):(g=b,k=b.x,h=a,a=a.x),c.x<e.x?(b=c,p=c.x,m=e,c=e.x):(b=e,p=e.x,m=c,c=c.x)):
-(a.y<b.y?(g=a,k=a.y,h=b,a=b.y):(g=b,k=b.y,h=a,a=a.y),c.y<e.y?(b=c,p=c.y,m=e,c=e.y):(b=e,p=e.y,m=c,c=c.y));return k<=p?a<p?[]:a===p?f?[]:[b]:a<=c?[b,h]:[b,m]:k>c?[]:k===c?f?[]:[g]:a<=c?[g,h]:[g,m]}function f(a,b,c,d){var e=b.x-a.x,f=b.y-a.y;b=c.x-a.x;c=c.y-a.y;var g=d.x-a.x;d=d.y-a.y;a=e*c-f*b;e=e*d-f*g;return Math.abs(a)>Number.EPSILON?(b=g*c-d*b,0<a?0<=e&&0<=b:0<=e||0<=b):0<e}c(a);b.forEach(c);var g,h,k,m,q,l={};k=a.concat();g=0;for(h=b.length;g<h;g++)Array.prototype.push.apply(k,b[g]);g=0;for(h=
-k.length;g<h;g++)q=k[g].x+":"+k[g].y,void 0!==l[q]&&console.warn("THREE.ShapeUtils: Duplicate point",q,g),l[q]=g;g=function(a,b){function c(a,b){var d=h.length-1,e=a-1;0>e&&(e=d);var g=a+1;g>d&&(g=0);d=f(h[a],h[e],h[g],k[b]);if(!d)return!1;d=k.length-1;e=b-1;0>e&&(e=d);g=b+1;g>d&&(g=0);return(d=f(k[b],k[e],k[g],h[a]))?!0:!1}function d(a,b){var c,f;for(c=0;c<h.length;c++)if(f=c+1,f%=h.length,f=e(a,b,h[c],h[f],!0),0<f.length)return!0;return!1}function g(a,c){var d,f,h,k;for(d=0;d<m.length;d++)for(f=
-b[m[d]],h=0;h<f.length;h++)if(k=h+1,k%=f.length,k=e(a,c,f[h],f[k],!0),0<k.length)return!0;return!1}var h=a.concat(),k,m=[],q,l,p,n,v,B=[],C,z,E,G=0;for(q=b.length;G<q;G++)m.push(G);C=0;for(var K=2*m.length;0<m.length;){K--;if(0>K){console.log("Infinite Loop! Holes left:"+m.length+", Probably Hole outside Shape!");break}for(l=C;l<h.length;l++){p=h[l];q=-1;for(G=0;G<m.length;G++)if(n=m[G],v=p.x+":"+p.y+":"+n,void 0===B[v]){k=b[n];for(z=0;z<k.length;z++)if(n=k[z],c(l,z)&&!d(p,n)&&!g(p,n)){q=z;m.splice(G,
-1);C=h.slice(0,l+1);n=h.slice(l);z=k.slice(q);E=k.slice(0,q+1);h=C.concat(z).concat(E).concat(n);C=l;break}if(0<=q)break;B[v]=!0}if(0<=q)break}}return h}(a,b);var p=Ia.triangulate(g,!1);g=0;for(h=p.length;g<h;g++)for(m=p[g],k=0;3>k;k++)q=m[k].x+":"+m[k].y,q=l[q],void 0!==q&&(m[k]=q);return p.concat()},isClockWise:function(a){return 0>Ia.area(a)}};cb.prototype=Object.create(J.prototype);cb.prototype.constructor=cb;Ga.prototype=Object.create(E.prototype);Ga.prototype.constructor=Ga;Ga.prototype.getArrays=
-function(){var a=this.getAttribute("position"),a=a?Array.prototype.slice.call(a.array):[],b=this.getAttribute("uv"),b=b?Array.prototype.slice.call(b.array):[],c=this.index,c=c?Array.prototype.slice.call(c.array):[];return{position:a,uv:b,index:c}};Ga.prototype.addShapeList=function(a,b){var c=a.length;b.arrays=this.getArrays();for(var d=0;d<c;d++)this.addShape(a[d],b);this.setIndex(b.arrays.index);this.addAttribute("position",new B(b.arrays.position,3));this.addAttribute("uv",new B(b.arrays.uv,2))};
-Ga.prototype.addShape=function(a,b){function c(a,b,c){b||console.error("THREE.ExtrudeGeometry: vec does not exist");return b.clone().multiplyScalar(c).add(a)}function d(a,b,c){var d,e,f;e=a.x-b.x;f=a.y-b.y;d=c.x-a.x;var g=c.y-a.y,h=e*e+f*f;if(Math.abs(e*g-f*d)>Number.EPSILON){var k=Math.sqrt(h),m=Math.sqrt(d*d+g*g),h=b.x-f/k;b=b.y+e/k;g=((c.x-g/m-h)*g-(c.y+d/m-b)*d)/(e*g-f*d);d=h+e*g-a.x;e=b+f*g-a.y;f=d*d+e*e;if(2>=f)return new C(d,e);f=Math.sqrt(f/2)}else a=!1,e>Number.EPSILON?d>Number.EPSILON&&
-(a=!0):e<-Number.EPSILON?d<-Number.EPSILON&&(a=!0):Math.sign(f)===Math.sign(g)&&(a=!0),a?(d=-f,f=Math.sqrt(h)):(d=e,e=f,f=Math.sqrt(h/2));return new C(d/f,e/f)}function e(a,b){var c,d;for(L=a.length;0<=--L;){c=L;d=L-1;0>d&&(d=a.length-1);var e,f=H+2*y;for(e=0;e<f;e++){var g=ba*e,m=ba*(e+1),l=b+d+g,p=b+d+m,m=b+c+m;h(b+c+g);h(l);h(m);h(l);h(p);h(m);g=q.length/3;g=D.generateSideWallUV(Z,q,g-6,g-3,g-2,g-1);k(g[0]);k(g[1]);k(g[3]);k(g[1]);k(g[2]);k(g[3])}}}function f(a,b,c){r.push(a);r.push(b);r.push(c)}
-function g(a,b,c){h(a);h(b);h(c);a=q.length/3;a=D.generateTopUV(Z,q,a-3,a-2,a-1);k(a[0]);k(a[1]);k(a[2])}function h(a){l.push(q.length/3);q.push(r[3*a+0]);q.push(r[3*a+1]);q.push(r[3*a+2])}function k(a){p.push(a.x);p.push(a.y)}var m=b.arrays?b.arrays:this.getArrays(),q=m.position,l=m.index,p=m.uv,r=[],m=void 0!==b.amount?b.amount:100,z=void 0!==b.bevelThickness?b.bevelThickness:6,t=void 0!==b.bevelSize?b.bevelSize:z-2,y=void 0!==b.bevelSegments?b.bevelSegments:3,x=void 0!==b.bevelEnabled?b.bevelEnabled:
-!0,u=void 0!==b.curveSegments?b.curveSegments:12,H=void 0!==b.steps?b.steps:1,w=b.extrudePath,I,G=!1,D=void 0!==b.UVGenerator?b.UVGenerator:cb.WorldUVGenerator,O,E,F,K;w&&(I=w.getSpacedPoints(H),G=!0,x=!1,O=void 0!==b.frames?b.frames:w.computeFrenetFrames(H,!1),E=new n,F=new n,K=new n);x||(t=z=y=0);var T,J,U,Z=this,w=a.extractPoints(u),u=w.shape,P=w.holes;if(!Ia.isClockWise(u))for(u=u.reverse(),J=0,U=P.length;J<U;J++)T=P[J],Ia.isClockWise(T)&&(P[J]=T.reverse());var M=Ia.triangulateShape(u,P),V=u;
-J=0;for(U=P.length;J<U;J++)T=P[J],u=u.concat(T);var R,S,N,Y,Q,ba=u.length,X,fa=M.length,w=[],L=0;N=V.length;R=N-1;for(S=L+1;L<N;L++,R++,S++)R===N&&(R=0),S===N&&(S=0),w[L]=d(V[L],V[R],V[S]);var ha=[],ea,ia=w.concat();J=0;for(U=P.length;J<U;J++){T=P[J];ea=[];L=0;N=T.length;R=N-1;for(S=L+1;L<N;L++,R++,S++)R===N&&(R=0),S===N&&(S=0),ea[L]=d(T[L],T[R],T[S]);ha.push(ea);ia=ia.concat(ea)}for(R=0;R<y;R++){N=R/y;Y=z*Math.cos(N*Math.PI/2);S=t*Math.sin(N*Math.PI/2);L=0;for(N=V.length;L<N;L++)Q=c(V[L],w[L],S),
-f(Q.x,Q.y,-Y);J=0;for(U=P.length;J<U;J++)for(T=P[J],ea=ha[J],L=0,N=T.length;L<N;L++)Q=c(T[L],ea[L],S),f(Q.x,Q.y,-Y)}S=t;for(L=0;L<ba;L++)Q=x?c(u[L],ia[L],S):u[L],G?(F.copy(O.normals[0]).multiplyScalar(Q.x),E.copy(O.binormals[0]).multiplyScalar(Q.y),K.copy(I[0]).add(F).add(E),f(K.x,K.y,K.z)):f(Q.x,Q.y,0);for(N=1;N<=H;N++)for(L=0;L<ba;L++)Q=x?c(u[L],ia[L],S):u[L],G?(F.copy(O.normals[N]).multiplyScalar(Q.x),E.copy(O.binormals[N]).multiplyScalar(Q.y),K.copy(I[N]).add(F).add(E),f(K.x,K.y,K.z)):f(Q.x,Q.y,
-m/H*N);for(R=y-1;0<=R;R--){N=R/y;Y=z*Math.cos(N*Math.PI/2);S=t*Math.sin(N*Math.PI/2);L=0;for(N=V.length;L<N;L++)Q=c(V[L],w[L],S),f(Q.x,Q.y,m+Y);J=0;for(U=P.length;J<U;J++)for(T=P[J],ea=ha[J],L=0,N=T.length;L<N;L++)Q=c(T[L],ea[L],S),G?f(Q.x,Q.y+I[H-1].y,I[H-1].x+Y):f(Q.x,Q.y,m+Y)}(function(){var a=q.length/3;if(x){var c=0*ba;for(L=0;L<fa;L++)X=M[L],g(X[2]+c,X[1]+c,X[0]+c);c=ba*(H+2*y);for(L=0;L<fa;L++)X=M[L],g(X[0]+c,X[1]+c,X[2]+c)}else{for(L=0;L<fa;L++)X=M[L],g(X[2],X[1],X[0]);for(L=0;L<fa;L++)X=
-M[L],g(X[0]+ba*H,X[1]+ba*H,X[2]+ba*H)}Z.addGroup(a,q.length/3-a,void 0!==b.material?b.material:0)})();(function(){var a=q.length/3,c=0;e(V,c);c+=V.length;J=0;for(U=P.length;J<U;J++)T=P[J],e(T,c),c+=T.length;Z.addGroup(a,q.length/3-a,void 0!==b.extrudeMaterial?b.extrudeMaterial:1)})();b.arrays||(this.setIndex(l),this.addAttribute("position",new B(q,3)),this.addAttribute("uv",new B(b.arrays.uv,2)))};cb.WorldUVGenerator={generateTopUV:function(a,b,c,d,e){a=b[3*d];d=b[3*d+1];var f=b[3*e];e=b[3*e+1];return[new C(b[3*
-c],b[3*c+1]),new C(a,d),new C(f,e)]},generateSideWallUV:function(a,b,c,d,e,f){a=b[3*c];var g=b[3*c+1];c=b[3*c+2];var h=b[3*d],k=b[3*d+1];d=b[3*d+2];var m=b[3*e],l=b[3*e+1];e=b[3*e+2];var n=b[3*f],p=b[3*f+1];b=b[3*f+2];return.01>Math.abs(g-k)?[new C(a,1-c),new C(h,1-d),new C(m,1-e),new C(n,1-b)]:[new C(g,1-c),new C(k,1-d),new C(l,1-e),new C(p,1-b)]}};Lc.prototype=Object.create(J.prototype);Lc.prototype.constructor=Lc;Ub.prototype=Object.create(Ga.prototype);Ub.prototype.constructor=Ub;Mc.prototype=
-Object.create(J.prototype);Mc.prototype.constructor=Mc;mb.prototype=Object.create(E.prototype);mb.prototype.constructor=mb;Nc.prototype=Object.create(J.prototype);Nc.prototype.constructor=Nc;Vb.prototype=Object.create(E.prototype);Vb.prototype.constructor=Vb;Oc.prototype=Object.create(J.prototype);Oc.prototype.constructor=Oc;Wb.prototype=Object.create(E.prototype);Wb.prototype.constructor=Wb;Xb.prototype=Object.create(J.prototype);Xb.prototype.constructor=Xb;Yb.prototype=Object.create(E.prototype);
-Yb.prototype.constructor=Yb;Zb.prototype=Object.create(E.prototype);Zb.prototype.constructor=Zb;nb.prototype=Object.create(J.prototype);nb.prototype.constructor=nb;Ua.prototype=Object.create(E.prototype);Ua.prototype.constructor=Ua;Pc.prototype=Object.create(nb.prototype);Pc.prototype.constructor=Pc;Qc.prototype=Object.create(Ua.prototype);Qc.prototype.constructor=Qc;Rc.prototype=Object.create(J.prototype);Rc.prototype.constructor=Rc;$b.prototype=Object.create(E.prototype);$b.prototype.constructor=
-$b;var Ma=Object.freeze({WireframeGeometry:Mb,ParametricGeometry:Cc,ParametricBufferGeometry:Nb,TetrahedronGeometry:Ec,TetrahedronBufferGeometry:Ob,OctahedronGeometry:Fc,OctahedronBufferGeometry:lb,IcosahedronGeometry:Gc,IcosahedronBufferGeometry:Pb,DodecahedronGeometry:Hc,DodecahedronBufferGeometry:Qb,PolyhedronGeometry:Dc,PolyhedronBufferGeometry:za,TubeGeometry:Ic,TubeBufferGeometry:Rb,TorusKnotGeometry:Jc,TorusKnotBufferGeometry:Sb,TorusGeometry:Kc,TorusBufferGeometry:Tb,TextGeometry:Lc,TextBufferGeometry:Ub,
-SphereGeometry:Mc,SphereBufferGeometry:mb,RingGeometry:Nc,RingBufferGeometry:Vb,PlaneGeometry:vc,PlaneBufferGeometry:jb,LatheGeometry:Oc,LatheBufferGeometry:Wb,ShapeGeometry:Xb,ShapeBufferGeometry:Yb,ExtrudeGeometry:cb,ExtrudeBufferGeometry:Ga,EdgesGeometry:Zb,ConeGeometry:Pc,ConeBufferGeometry:Qc,CylinderGeometry:nb,CylinderBufferGeometry:Ua,CircleGeometry:Rc,CircleBufferGeometry:$b,BoxGeometry:Gb,BoxBufferGeometry:ib});ac.prototype=Object.create(ra.prototype);ac.prototype.constructor=ac;ac.prototype.isShadowMaterial=
-!0;bc.prototype=Object.create(ra.prototype);bc.prototype.constructor=bc;bc.prototype.isRawShaderMaterial=!0;Pa.prototype=Object.create(U.prototype);Pa.prototype.constructor=Pa;Pa.prototype.isMeshStandardMaterial=!0;Pa.prototype.copy=function(a){U.prototype.copy.call(this,a);this.defines={STANDARD:""};this.color.copy(a.color);this.roughness=a.roughness;this.metalness=a.metalness;this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=
-a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.roughnessMap=a.roughnessMap;this.metalnessMap=a.metalnessMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.envMapIntensity=a.envMapIntensity;
-this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};ob.prototype=Object.create(Pa.prototype);ob.prototype.constructor=ob;ob.prototype.isMeshPhysicalMaterial=!0;ob.prototype.copy=function(a){Pa.prototype.copy.call(this,a);this.defines={PHYSICAL:""};this.reflectivity=
-a.reflectivity;this.clearCoat=a.clearCoat;this.clearCoatRoughness=a.clearCoatRoughness;return this};Ja.prototype=Object.create(U.prototype);Ja.prototype.constructor=Ja;Ja.prototype.isMeshPhongMaterial=!0;Ja.prototype.copy=function(a){U.prototype.copy.call(this,a);this.color.copy(a.color);this.specular.copy(a.specular);this.shininess=a.shininess;this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);
-this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;
-this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};pb.prototype=Object.create(Ja.prototype);pb.prototype.constructor=pb;pb.prototype.isMeshToonMaterial=!0;pb.prototype.copy=function(a){Ja.prototype.copy.call(this,a);this.gradientMap=a.gradientMap;return this};qb.prototype=Object.create(U.prototype);qb.prototype.constructor=
-qb;qb.prototype.isMeshNormalMaterial=!0;qb.prototype.copy=function(a){U.prototype.copy.call(this,a);this.bumpMap=a.bumpMap;this.bumpScale=a.bumpScale;this.normalMap=a.normalMap;this.normalScale.copy(a.normalScale);this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};
-rb.prototype=Object.create(U.prototype);rb.prototype.constructor=rb;rb.prototype.isMeshLambertMaterial=!0;rb.prototype.copy=function(a){U.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.emissive.copy(a.emissive);this.emissiveMap=a.emissiveMap;this.emissiveIntensity=a.emissiveIntensity;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=
-a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.morphNormals=a.morphNormals;return this};sb.prototype=Object.create(U.prototype);sb.prototype.constructor=sb;sb.prototype.isLineDashedMaterial=!0;sb.prototype.copy=function(a){U.prototype.copy.call(this,
-a);this.color.copy(a.color);this.linewidth=a.linewidth;this.scale=a.scale;this.dashSize=a.dashSize;this.gapSize=a.gapSize;return this};var mg=Object.freeze({ShadowMaterial:ac,SpriteMaterial:bb,RawShaderMaterial:bc,ShaderMaterial:ra,PointsMaterial:Fa,MeshPhysicalMaterial:ob,MeshStandardMaterial:Pa,MeshPhongMaterial:Ja,MeshToonMaterial:pb,MeshNormalMaterial:qb,MeshLambertMaterial:rb,MeshDepthMaterial:Za,MeshBasicMaterial:ya,LineDashedMaterial:sb,LineBasicMaterial:ea,Material:U}),ed={enabled:!1,files:{},
-add:function(a,b){!1!==this.enabled&&(this.files[a]=b)},get:function(a){if(!1!==this.enabled)return this.files[a]},remove:function(a){delete this.files[a]},clear:function(){this.files={}}},va=new Zd;Object.assign(Ka.prototype,{load:function(a,b,c,d){void 0===a&&(a="");void 0!==this.path&&(a=this.path+a);var e=this,f=ed.get(a);if(void 0!==f)return e.manager.itemStart(a),setTimeout(function(){b&&b(f);e.manager.itemEnd(a)},0),f;var g=a.match(/^data:(.*?)(;base64)?,(.*)$/);if(g){var h=g[1],k=!!g[2],g=
-g[3],g=window.decodeURIComponent(g);k&&(g=window.atob(g));try{var m,l=(this.responseType||"").toLowerCase();switch(l){case "arraybuffer":case "blob":m=new ArrayBuffer(g.length);for(var n=new Uint8Array(m),k=0;k<g.length;k++)n[k]=g.charCodeAt(k);"blob"===l&&(m=new Blob([m],{type:h}));break;case "document":m=(new DOMParser).parseFromString(g,h);break;case "json":m=JSON.parse(g);break;default:m=g}window.setTimeout(function(){b&&b(m);e.manager.itemEnd(a)},0)}catch(r){window.setTimeout(function(){d&&d(r);
-e.manager.itemEnd(a);e.manager.itemError(a)},0)}}else{var p=new XMLHttpRequest;p.open("GET",a,!0);p.addEventListener("load",function(c){var f=c.target.response;ed.add(a,f);200===this.status?(b&&b(f),e.manager.itemEnd(a)):0===this.status?(console.warn("THREE.FileLoader: HTTP Status 0 received."),b&&b(f),e.manager.itemEnd(a)):(d&&d(c),e.manager.itemEnd(a),e.manager.itemError(a))},!1);void 0!==c&&p.addEventListener("progress",function(a){c(a)},!1);p.addEventListener("error",function(b){d&&d(b);e.manager.itemEnd(a);
-e.manager.itemError(a)},!1);void 0!==this.responseType&&(p.responseType=this.responseType);void 0!==this.withCredentials&&(p.withCredentials=this.withCredentials);p.overrideMimeType&&p.overrideMimeType(void 0!==this.mimeType?this.mimeType:"text/plain");for(h in this.requestHeader)p.setRequestHeader(h,this.requestHeader[h]);p.send(null)}e.manager.itemStart(a);return p},setPath:function(a){this.path=a;return this},setResponseType:function(a){this.responseType=a;return this},setWithCredentials:function(a){this.withCredentials=
-a;return this},setMimeType:function(a){this.mimeType=a;return this},setRequestHeader:function(a){this.requestHeader=a;return this}});Object.assign(Oe.prototype,{load:function(a,b,c,d){function e(e){k.load(a[e],function(a){a=f._parser(a,!0);g[e]={width:a.width,height:a.height,format:a.format,mipmaps:a.mipmaps};m+=1;6===m&&(1===a.mipmapCount&&(h.minFilter=1006),h.format=a.format,h.needsUpdate=!0,b&&b(h))},c,d)}var f=this,g=[],h=new Lb;h.image=g;var k=new Ka(this.manager);k.setPath(this.path);k.setResponseType("arraybuffer");
-if(Array.isArray(a))for(var m=0,l=0,n=a.length;l<n;++l)e(l);else k.load(a,function(a){a=f._parser(a,!0);if(a.isCubemap)for(var c=a.mipmaps.length/a.mipmapCount,d=0;d<c;d++){g[d]={mipmaps:[]};for(var e=0;e<a.mipmapCount;e++)g[d].mipmaps.push(a.mipmaps[d*a.mipmapCount+e]),g[d].format=a.format,g[d].width=a.width,g[d].height=a.height}else h.image.width=a.width,h.image.height=a.height,h.mipmaps=a.mipmaps;1===a.mipmapCount&&(h.minFilter=1006);h.format=a.format;h.needsUpdate=!0;b&&b(h)},c,d);return h},setPath:function(a){this.path=
-a;return this}});Object.assign($d.prototype,{load:function(a,b,c,d){var e=this,f=new db,g=new Ka(this.manager);g.setResponseType("arraybuffer");g.load(a,function(a){if(a=e._parser(a))void 0!==a.image?f.image=a.image:void 0!==a.data&&(f.image.width=a.width,f.image.height=a.height,f.image.data=a.data),f.wrapS=void 0!==a.wrapS?a.wrapS:1001,f.wrapT=void 0!==a.wrapT?a.wrapT:1001,f.magFilter=void 0!==a.magFilter?a.magFilter:1006,f.minFilter=void 0!==a.minFilter?a.minFilter:1008,f.anisotropy=void 0!==a.anisotropy?
-a.anisotropy:1,void 0!==a.format&&(f.format=a.format),void 0!==a.type&&(f.type=a.type),void 0!==a.mipmaps&&(f.mipmaps=a.mipmaps),1===a.mipmapCount&&(f.minFilter=1006),f.needsUpdate=!0,b&&b(f,a)},c,d);return f}});Object.assign(Sc.prototype,{load:function(a,b,c,d){void 0===a&&(a="");void 0!==this.path&&(a=this.path+a);var e=this,f=ed.get(a);if(void 0!==f)return e.manager.itemStart(a),setTimeout(function(){b&&b(f);e.manager.itemEnd(a)},0),f;c=document.createElementNS("http://www.w3.org/1999/xhtml","img");
-c.addEventListener("load",function(){ed.add(a,this);b&&b(this);e.manager.itemEnd(a)},!1);c.addEventListener("error",function(b){d&&d(b);e.manager.itemEnd(a);e.manager.itemError(a)},!1);"data:"!==a.substr(0,5)&&void 0!==this.crossOrigin&&(c.crossOrigin=this.crossOrigin);e.manager.itemStart(a);c.src=a;return c},setCrossOrigin:function(a){this.crossOrigin=a;return this},setPath:function(a){this.path=a;return this}});Object.assign(ae.prototype,{load:function(a,b,c,d){function e(c){g.load(a[c],function(a){f.images[c]=
-a;h++;6===h&&(f.needsUpdate=!0,b&&b(f))},void 0,d)}var f=new Xa,g=new Sc(this.manager);g.setCrossOrigin(this.crossOrigin);g.setPath(this.path);var h=0;for(c=0;c<a.length;++c)e(c);return f},setCrossOrigin:function(a){this.crossOrigin=a;return this},setPath:function(a){this.path=a;return this}});Object.assign(rd.prototype,{load:function(a,b,c,d){var e=new Sc(this.manager);e.setCrossOrigin(this.crossOrigin);e.setPath(this.path);var f=new ba;f.image=e.load(a,function(){var c=0<a.search(/\.(jpg|jpeg)$/)||
-0===a.search(/^data\:image\/jpeg/);f.format=c?1022:1023;f.needsUpdate=!0;void 0!==b&&b(f)},c,d);return f},setCrossOrigin:function(a){this.crossOrigin=a;return this},setPath:function(a){this.path=a;return this}});na.prototype=Object.assign(Object.create(z.prototype),{constructor:na,isLight:!0,copy:function(a){z.prototype.copy.call(this,a);this.color.copy(a.color);this.intensity=a.intensity;return this},toJSON:function(a){a=z.prototype.toJSON.call(this,a);a.object.color=this.color.getHex();a.object.intensity=
-this.intensity;void 0!==this.groundColor&&(a.object.groundColor=this.groundColor.getHex());void 0!==this.distance&&(a.object.distance=this.distance);void 0!==this.angle&&(a.object.angle=this.angle);void 0!==this.decay&&(a.object.decay=this.decay);void 0!==this.penumbra&&(a.object.penumbra=this.penumbra);void 0!==this.shadow&&(a.object.shadow=this.shadow.toJSON());return a}});sd.prototype=Object.assign(Object.create(na.prototype),{constructor:sd,isHemisphereLight:!0,copy:function(a){na.prototype.copy.call(this,
-a);this.groundColor.copy(a.groundColor);return this}});Object.assign(tb.prototype,{copy:function(a){this.camera=a.camera.clone();this.bias=a.bias;this.radius=a.radius;this.mapSize.copy(a.mapSize);return this},clone:function(){return(new this.constructor).copy(this)},toJSON:function(){var a={};0!==this.bias&&(a.bias=this.bias);1!==this.radius&&(a.radius=this.radius);if(512!==this.mapSize.x||512!==this.mapSize.y)a.mapSize=this.mapSize.toArray();a.camera=this.camera.toJSON(!1).object;delete a.camera.matrix;
-return a}});td.prototype=Object.assign(Object.create(tb.prototype),{constructor:td,isSpotLightShadow:!0,update:function(a){var b=this.camera,c=2*Y.RAD2DEG*a.angle,d=this.mapSize.width/this.mapSize.height;a=a.distance||b.far;if(c!==b.fov||d!==b.aspect||a!==b.far)b.fov=c,b.aspect=d,b.far=a,b.updateProjectionMatrix()}});ud.prototype=Object.assign(Object.create(na.prototype),{constructor:ud,isSpotLight:!0,copy:function(a){na.prototype.copy.call(this,a);this.distance=a.distance;this.angle=a.angle;this.penumbra=
-a.penumbra;this.decay=a.decay;this.target=a.target.clone();this.shadow=a.shadow.clone();return this}});vd.prototype=Object.assign(Object.create(na.prototype),{constructor:vd,isPointLight:!0,copy:function(a){na.prototype.copy.call(this,a);this.distance=a.distance;this.decay=a.decay;this.shadow=a.shadow.clone();return this}});wd.prototype=Object.assign(Object.create(tb.prototype),{constructor:wd});xd.prototype=Object.assign(Object.create(na.prototype),{constructor:xd,isDirectionalLight:!0,copy:function(a){na.prototype.copy.call(this,
-a);this.target=a.target.clone();this.shadow=a.shadow.clone();return this}});yd.prototype=Object.assign(Object.create(na.prototype),{constructor:yd,isAmbientLight:!0});zd.prototype=Object.assign(Object.create(na.prototype),{constructor:zd,isRectAreaLight:!0,copy:function(a){na.prototype.copy.call(this,a);this.width=a.width;this.height=a.height;return this},toJSON:function(a){a=na.prototype.toJSON.call(this,a);a.object.width=this.width;a.object.height=this.height;return a}});var ia={arraySlice:function(a,
-b,c){return ia.isTypedArray(a)?new a.constructor(a.subarray(b,void 0!==c?c:a.length)):a.slice(b,c)},convertArray:function(a,b,c){return!a||!c&&a.constructor===b?a:"number"===typeof b.BYTES_PER_ELEMENT?new b(a):Array.prototype.slice.call(a)},isTypedArray:function(a){return ArrayBuffer.isView(a)&&!(a instanceof DataView)},getKeyframeOrder:function(a){for(var b=a.length,c=Array(b),d=0;d!==b;++d)c[d]=d;c.sort(function(b,c){return a[b]-a[c]});return c},sortedArray:function(a,b,c){for(var d=a.length,e=
-new a.constructor(d),f=0,g=0;g!==d;++f)for(var h=c[f]*b,k=0;k!==b;++k)e[g++]=a[h+k];return e},flattenJSON:function(a,b,c,d){for(var e=1,f=a[0];void 0!==f&&void 0===f[d];)f=a[e++];if(void 0!==f){var g=f[d];if(void 0!==g)if(Array.isArray(g)){do g=f[d],void 0!==g&&(b.push(f.time),c.push.apply(c,g)),f=a[e++];while(void 0!==f)}else if(void 0!==g.toArray){do g=f[d],void 0!==g&&(b.push(f.time),g.toArray(c,c.length)),f=a[e++];while(void 0!==f)}else{do g=f[d],void 0!==g&&(b.push(f.time),c.push(g)),f=a[e++];
-while(void 0!==f)}}}};Object.assign(wa.prototype,{evaluate:function(a){var b=this.parameterPositions,c=this._cachedIndex,d=b[c],e=b[c-1];a:{b:{c:{d:if(!(a<d)){for(var f=c+2;;){if(void 0===d){if(a<e)break d;this._cachedIndex=c=b.length;return this.afterEnd_(c-1,a,e)}if(c===f)break;e=d;d=b[++c];if(a<d)break b}d=b.length;break c}if(a>=e)break a;else{f=b[1];a<f&&(c=2,e=f);for(f=c-2;;){if(void 0===e)return this._cachedIndex=0,this.beforeStart_(0,a,d);if(c===f)break;d=e;e=b[--c-1];if(a>=e)break b}d=c;c=
-0}}for(;c<d;)e=c+d>>>1,a<b[e]?d=e:c=e+1;d=b[c];e=b[c-1];if(void 0===e)return this._cachedIndex=0,this.beforeStart_(0,a,d);if(void 0===d)return this._cachedIndex=c=b.length,this.afterEnd_(c-1,e,a)}this._cachedIndex=c;this.intervalChanged_(c,e,d)}return this.interpolate_(c,e,a,d)},settings:null,DefaultSettings_:{},getSettings_:function(){return this.settings||this.DefaultSettings_},copySampleValue_:function(a){var b=this.resultBuffer,c=this.sampleValues,d=this.valueSize;a*=d;for(var e=0;e!==d;++e)b[e]=
-c[a+e];return b},interpolate_:function(a,b,c,d){throw Error("call to abstract method");},intervalChanged_:function(a,b,c){}});Object.assign(wa.prototype,{beforeStart_:wa.prototype.copySampleValue_,afterEnd_:wa.prototype.copySampleValue_});Ad.prototype=Object.assign(Object.create(wa.prototype),{constructor:Ad,DefaultSettings_:{endingStart:2400,endingEnd:2400},intervalChanged_:function(a,b,c){var d=this.parameterPositions,e=a-2,f=a+1,g=d[e],h=d[f];if(void 0===g)switch(this.getSettings_().endingStart){case 2401:e=
-a;g=2*b-c;break;case 2402:e=d.length-2;g=b+d[e]-d[e+1];break;default:e=a,g=c}if(void 0===h)switch(this.getSettings_().endingEnd){case 2401:f=a;h=2*c-b;break;case 2402:f=1;h=c+d[1]-d[0];break;default:f=a-1,h=b}a=.5*(c-b);d=this.valueSize;this._weightPrev=a/(b-g);this._weightNext=a/(h-c);this._offsetPrev=e*d;this._offsetNext=f*d},interpolate_:function(a,b,c,d){var e=this.resultBuffer,f=this.sampleValues,g=this.valueSize;a*=g;var h=a-g,k=this._offsetPrev,m=this._offsetNext,l=this._weightPrev,n=this._weightNext,
-p=(c-b)/(d-b);c=p*p;d=c*p;b=-l*d+2*l*c-l*p;l=(1+l)*d+(-1.5-2*l)*c+(-.5+l)*p+1;p=(-1-n)*d+(1.5+n)*c+.5*p;n=n*d-n*c;for(c=0;c!==g;++c)e[c]=b*f[k+c]+l*f[h+c]+p*f[a+c]+n*f[m+c];return e}});Tc.prototype=Object.assign(Object.create(wa.prototype),{constructor:Tc,interpolate_:function(a,b,c,d){var e=this.resultBuffer,f=this.sampleValues,g=this.valueSize;a*=g;var h=a-g;b=(c-b)/(d-b);c=1-b;for(d=0;d!==g;++d)e[d]=f[h+d]*c+f[a+d]*b;return e}});Bd.prototype=Object.assign(Object.create(wa.prototype),{constructor:Bd,
-interpolate_:function(a,b,c,d){return this.copySampleValue_(a-1)}});var Wa;Wa={TimeBufferType:Float32Array,ValueBufferType:Float32Array,DefaultInterpolation:2301,InterpolantFactoryMethodDiscrete:function(a){return new Bd(this.times,this.values,this.getValueSize(),a)},InterpolantFactoryMethodLinear:function(a){return new Tc(this.times,this.values,this.getValueSize(),a)},InterpolantFactoryMethodSmooth:function(a){return new Ad(this.times,this.values,this.getValueSize(),a)},setInterpolation:function(a){var b;
-switch(a){case 2300:b=this.InterpolantFactoryMethodDiscrete;break;case 2301:b=this.InterpolantFactoryMethodLinear;break;case 2302:b=this.InterpolantFactoryMethodSmooth}if(void 0===b){b="unsupported interpolation for "+this.ValueTypeName+" keyframe track named "+this.name;if(void 0===this.createInterpolant)if(a!==this.DefaultInterpolation)this.setInterpolation(this.DefaultInterpolation);else throw Error(b);console.warn("THREE.KeyframeTrackPrototype:",b)}else this.createInterpolant=b},getInterpolation:function(){switch(this.createInterpolant){case this.InterpolantFactoryMethodDiscrete:return 2300;
-case this.InterpolantFactoryMethodLinear:return 2301;case this.InterpolantFactoryMethodSmooth:return 2302}},getValueSize:function(){return this.values.length/this.times.length},shift:function(a){if(0!==a)for(var b=this.times,c=0,d=b.length;c!==d;++c)b[c]+=a;return this},scale:function(a){if(1!==a)for(var b=this.times,c=0,d=b.length;c!==d;++c)b[c]*=a;return this},trim:function(a,b){for(var c=this.times,d=c.length,e=0,f=d-1;e!==d&&c[e]<a;)++e;for(;-1!==f&&c[f]>b;)--f;++f;if(0!==e||f!==d)e>=f&&(f=Math.max(f,
-1),e=f-1),d=this.getValueSize(),this.times=ia.arraySlice(c,e,f),this.values=ia.arraySlice(this.values,e*d,f*d);return this},validate:function(){var a=!0,b=this.getValueSize();0!==b-Math.floor(b)&&(console.error("THREE.KeyframeTrackPrototype: Invalid value size in track.",this),a=!1);var c=this.times,b=this.values,d=c.length;0===d&&(console.error("THREE.KeyframeTrackPrototype: Track is empty.",this),a=!1);for(var e=null,f=0;f!==d;f++){var g=c[f];if("number"===typeof g&&isNaN(g)){console.error("THREE.KeyframeTrackPrototype: Time is not a valid number.",
-this,f,g);a=!1;break}if(null!==e&&e>g){console.error("THREE.KeyframeTrackPrototype: Out of order keys.",this,f,g,e);a=!1;break}e=g}if(void 0!==b&&ia.isTypedArray(b))for(f=0,c=b.length;f!==c;++f)if(d=b[f],isNaN(d)){console.error("THREE.KeyframeTrackPrototype: Value is not a valid number.",this,f,d);a=!1;break}return a},optimize:function(){for(var a=this.times,b=this.values,c=this.getValueSize(),d=2302===this.getInterpolation(),e=1,f=a.length-1,g=1;g<f;++g){var h=!1,k=a[g];if(k!==a[g+1]&&(1!==g||k!==
-k[0]))if(d)h=!0;else for(var m=g*c,l=m-c,n=m+c,k=0;k!==c;++k){var p=b[m+k];if(p!==b[l+k]||p!==b[n+k]){h=!0;break}}if(h){if(g!==e)for(a[e]=a[g],h=g*c,m=e*c,k=0;k!==c;++k)b[m+k]=b[h+k];++e}}if(0<f){a[e]=a[f];h=f*c;m=e*c;for(k=0;k!==c;++k)b[m+k]=b[h+k];++e}e!==a.length&&(this.times=ia.arraySlice(a,0,e),this.values=ia.arraySlice(b,0,e*c));return this}};cc.prototype=Object.assign(Object.create(Wa),{constructor:cc,ValueTypeName:"vector"});Cd.prototype=Object.assign(Object.create(wa.prototype),{constructor:Cd,
-interpolate_:function(a,b,c,d){var e=this.resultBuffer,f=this.sampleValues,g=this.valueSize;a*=g;b=(c-b)/(d-b);for(c=a+g;a!==c;a+=4)oa.slerpFlat(e,0,f,a-g,f,a,b);return e}});Uc.prototype=Object.assign(Object.create(Wa),{constructor:Uc,ValueTypeName:"quaternion",DefaultInterpolation:2301,InterpolantFactoryMethodLinear:function(a){return new Cd(this.times,this.values,this.getValueSize(),a)},InterpolantFactoryMethodSmooth:void 0});dc.prototype=Object.assign(Object.create(Wa),{constructor:dc,ValueTypeName:"number"});
-Dd.prototype=Object.assign(Object.create(Wa),{constructor:Dd,ValueTypeName:"string",ValueBufferType:Array,DefaultInterpolation:2300,InterpolantFactoryMethodLinear:void 0,InterpolantFactoryMethodSmooth:void 0});Ed.prototype=Object.assign(Object.create(Wa),{constructor:Ed,ValueTypeName:"bool",ValueBufferType:Array,DefaultInterpolation:2300,InterpolantFactoryMethodLinear:void 0,InterpolantFactoryMethodSmooth:void 0});Fd.prototype=Object.assign(Object.create(Wa),{constructor:Fd,ValueTypeName:"color"});
-vb.prototype=Wa;Wa.constructor=vb;Object.assign(vb,{parse:function(a){if(void 0===a.type)throw Error("track type undefined, can not parse");var b=vb._getTrackTypeForValueTypeName(a.type);if(void 0===a.times){var c=[],d=[];ia.flattenJSON(a.keys,c,d,"value");a.times=c;a.values=d}return void 0!==b.parse?b.parse(a):new b(a.name,a.times,a.values,a.interpolation)},toJSON:function(a){var b=a.constructor;if(void 0!==b.toJSON)b=b.toJSON(a);else{var b={name:a.name,times:ia.convertArray(a.times,Array),values:ia.convertArray(a.values,
-Array)},c=a.getInterpolation();c!==a.DefaultInterpolation&&(b.interpolation=c)}b.type=a.ValueTypeName;return b},_getTrackTypeForValueTypeName:function(a){switch(a.toLowerCase()){case "scalar":case "double":case "float":case "number":case "integer":return dc;case "vector":case "vector2":case "vector3":case "vector4":return cc;case "color":return Fd;case "quaternion":return Uc;case "bool":case "boolean":return Ed;case "string":return Dd}throw Error("Unsupported typeName: "+a);}});Object.assign(Da,{parse:function(a){for(var b=
-[],c=a.tracks,d=1/(a.fps||1),e=0,f=c.length;e!==f;++e)b.push(vb.parse(c[e]).scale(d));return new Da(a.name,a.duration,b)},toJSON:function(a){var b=[],c=a.tracks;a={name:a.name,duration:a.duration,tracks:b};for(var d=0,e=c.length;d!==e;++d)b.push(vb.toJSON(c[d]));return a},CreateFromMorphTargetSequence:function(a,b,c,d){for(var e=b.length,f=[],g=0;g<e;g++){var h=[],k=[];h.push((g+e-1)%e,g,(g+1)%e);k.push(0,1,0);var m=ia.getKeyframeOrder(h),h=ia.sortedArray(h,1,m),k=ia.sortedArray(k,1,m);d||0!==h[0]||
-(h.push(e),k.push(k[0]));f.push((new dc(".morphTargetInfluences["+b[g].name+"]",h,k)).scale(1/c))}return new Da(a,-1,f)},findByName:function(a,b){var c=a;Array.isArray(a)||(c=a.geometry&&a.geometry.animations||a.animations);for(var d=0;d<c.length;d++)if(c[d].name===b)return c[d];return null},CreateClipsFromMorphTargetSequences:function(a,b,c){for(var d={},e=/^([\w-]*?)([\d]+)$/,f=0,g=a.length;f<g;f++){var h=a[f],k=h.name.match(e);if(k&&1<k.length){var m=k[1];(k=d[m])||(d[m]=k=[]);k.push(h)}}a=[];
-for(m in d)a.push(Da.CreateFromMorphTargetSequence(m,d[m],b,c));return a},parseAnimation:function(a,b){if(!a)return console.error("THREE.AnimationClip: No animation in JSONLoader data."),null;for(var c=function(a,b,c,d,e){if(0!==c.length){var f=[],g=[];ia.flattenJSON(c,f,g,d);0!==f.length&&e.push(new a(b,f,g))}},d=[],e=a.name||"default",f=a.length||-1,g=a.fps||30,h=a.hierarchy||[],k=0;k<h.length;k++){var m=h[k].keys;if(m&&0!==m.length)if(m[0].morphTargets){for(var f={},l=0;l<m.length;l++)if(m[l].morphTargets)for(var n=
-0;n<m[l].morphTargets.length;n++)f[m[l].morphTargets[n]]=-1;for(var p in f){for(var r=[],z=[],n=0;n!==m[l].morphTargets.length;++n){var t=m[l];r.push(t.time);z.push(t.morphTarget===p?1:0)}d.push(new dc(".morphTargetInfluence["+p+"]",r,z))}f=f.length*(g||1)}else l=".bones["+b[k].name+"]",c(cc,l+".position",m,"pos",d),c(Uc,l+".quaternion",m,"rot",d),c(cc,l+".scale",m,"scl",d)}return 0===d.length?null:new Da(e,f,d)}});Object.assign(Da.prototype,{resetDuration:function(){for(var a=0,b=0,c=this.tracks.length;b!==
-c;++b)var d=this.tracks[b],a=Math.max(a,d.times[d.times.length-1]);this.duration=a},trim:function(){for(var a=0;a<this.tracks.length;a++)this.tracks[a].trim(0,this.duration);return this},optimize:function(){for(var a=0;a<this.tracks.length;a++)this.tracks[a].optimize();return this}});Object.assign(Gd.prototype,{load:function(a,b,c,d){var e=this;(new Ka(e.manager)).load(a,function(a){b(e.parse(JSON.parse(a)))},c,d)},setTextures:function(a){this.textures=a},parse:function(a){function b(a){void 0===
-c[a]&&console.warn("THREE.MaterialLoader: Undefined texture",a);return c[a]}var c=this.textures,d=new mg[a.type];void 0!==a.uuid&&(d.uuid=a.uuid);void 0!==a.name&&(d.name=a.name);void 0!==a.color&&d.color.setHex(a.color);void 0!==a.roughness&&(d.roughness=a.roughness);void 0!==a.metalness&&(d.metalness=a.metalness);void 0!==a.emissive&&d.emissive.setHex(a.emissive);void 0!==a.specular&&d.specular.setHex(a.specular);void 0!==a.shininess&&(d.shininess=a.shininess);void 0!==a.clearCoat&&(d.clearCoat=
-a.clearCoat);void 0!==a.clearCoatRoughness&&(d.clearCoatRoughness=a.clearCoatRoughness);void 0!==a.uniforms&&(d.uniforms=a.uniforms);void 0!==a.vertexShader&&(d.vertexShader=a.vertexShader);void 0!==a.fragmentShader&&(d.fragmentShader=a.fragmentShader);void 0!==a.vertexColors&&(d.vertexColors=a.vertexColors);void 0!==a.fog&&(d.fog=a.fog);void 0!==a.shading&&(d.shading=a.shading);void 0!==a.blending&&(d.blending=a.blending);void 0!==a.side&&(d.side=a.side);void 0!==a.opacity&&(d.opacity=a.opacity);
-void 0!==a.transparent&&(d.transparent=a.transparent);void 0!==a.alphaTest&&(d.alphaTest=a.alphaTest);void 0!==a.depthTest&&(d.depthTest=a.depthTest);void 0!==a.depthWrite&&(d.depthWrite=a.depthWrite);void 0!==a.colorWrite&&(d.colorWrite=a.colorWrite);void 0!==a.wireframe&&(d.wireframe=a.wireframe);void 0!==a.wireframeLinewidth&&(d.wireframeLinewidth=a.wireframeLinewidth);void 0!==a.wireframeLinecap&&(d.wireframeLinecap=a.wireframeLinecap);void 0!==a.wireframeLinejoin&&(d.wireframeLinejoin=a.wireframeLinejoin);
-void 0!==a.skinning&&(d.skinning=a.skinning);void 0!==a.morphTargets&&(d.morphTargets=a.morphTargets);void 0!==a.size&&(d.size=a.size);void 0!==a.sizeAttenuation&&(d.sizeAttenuation=a.sizeAttenuation);void 0!==a.map&&(d.map=b(a.map));void 0!==a.alphaMap&&(d.alphaMap=b(a.alphaMap),d.transparent=!0);void 0!==a.bumpMap&&(d.bumpMap=b(a.bumpMap));void 0!==a.bumpScale&&(d.bumpScale=a.bumpScale);void 0!==a.normalMap&&(d.normalMap=b(a.normalMap));if(void 0!==a.normalScale){var e=a.normalScale;!1===Array.isArray(e)&&
-(e=[e,e]);d.normalScale=(new C).fromArray(e)}void 0!==a.displacementMap&&(d.displacementMap=b(a.displacementMap));void 0!==a.displacementScale&&(d.displacementScale=a.displacementScale);void 0!==a.displacementBias&&(d.displacementBias=a.displacementBias);void 0!==a.roughnessMap&&(d.roughnessMap=b(a.roughnessMap));void 0!==a.metalnessMap&&(d.metalnessMap=b(a.metalnessMap));void 0!==a.emissiveMap&&(d.emissiveMap=b(a.emissiveMap));void 0!==a.emissiveIntensity&&(d.emissiveIntensity=a.emissiveIntensity);
-void 0!==a.specularMap&&(d.specularMap=b(a.specularMap));void 0!==a.envMap&&(d.envMap=b(a.envMap));void 0!==a.reflectivity&&(d.reflectivity=a.reflectivity);void 0!==a.lightMap&&(d.lightMap=b(a.lightMap));void 0!==a.lightMapIntensity&&(d.lightMapIntensity=a.lightMapIntensity);void 0!==a.aoMap&&(d.aoMap=b(a.aoMap));void 0!==a.aoMapIntensity&&(d.aoMapIntensity=a.aoMapIntensity);void 0!==a.gradientMap&&(d.gradientMap=b(a.gradientMap));return d}});Object.assign(be.prototype,{load:function(a,b,c,d){var e=
-this;(new Ka(e.manager)).load(a,function(a){b(e.parse(JSON.parse(a)))},c,d)},parse:function(a){var b=new E,c=a.data.index;void 0!==c&&(c=new ef[c.type](c.array),b.setIndex(new Z(c,1)));var d=a.data.attributes,e;for(e in d){var f=d[e],c=new ef[f.type](f.array);b.addAttribute(e,new Z(c,f.itemSize,f.normalized))}e=a.data.groups||a.data.drawcalls||a.data.offsets;if(void 0!==e)for(c=0,d=e.length;c!==d;++c)f=e[c],b.addGroup(f.start,f.count,f.materialIndex);a=a.data.boundingSphere;void 0!==a&&(e=new n,void 0!==
-a.center&&e.fromArray(a.center),b.boundingSphere=new Ea(e,a.radius));return b}});var ef={Int8Array:Int8Array,Uint8Array:Uint8Array,Uint8ClampedArray:"undefined"!==typeof Uint8ClampedArray?Uint8ClampedArray:Uint8Array,Int16Array:Int16Array,Uint16Array:Uint16Array,Int32Array:Int32Array,Uint32Array:Uint32Array,Float32Array:Float32Array,Float64Array:Float64Array};ec.Handlers={handlers:[],add:function(a,b){this.handlers.push(a,b)},get:function(a){for(var b=this.handlers,c=0,d=b.length;c<d;c+=2){var e=
-b[c+1];if(b[c].test(a))return e}return null}};Object.assign(ec.prototype,{crossOrigin:void 0,extractUrlBase:function(a){a=a.split("/");if(1===a.length)return"./";a.pop();return a.join("/")+"/"},initMaterials:function(a,b,c){for(var d=[],e=0;e<a.length;++e)d[e]=this.createMaterial(a[e],b,c);return d},createMaterial:function(){var a={NoBlending:0,NormalBlending:1,AdditiveBlending:2,SubtractiveBlending:3,MultiplyBlending:4,CustomBlending:5},b=new G,c=new rd,d=new Gd;return function(e,f,g){function h(a,
-b,d,e,h){a=f+a;var m=ec.Handlers.get(a);null!==m?a=m.load(a):(c.setCrossOrigin(g),a=c.load(a));void 0!==b&&(a.repeat.fromArray(b),1!==b[0]&&(a.wrapS=1E3),1!==b[1]&&(a.wrapT=1E3));void 0!==d&&a.offset.fromArray(d);void 0!==e&&("repeat"===e[0]&&(a.wrapS=1E3),"mirror"===e[0]&&(a.wrapS=1002),"repeat"===e[1]&&(a.wrapT=1E3),"mirror"===e[1]&&(a.wrapT=1002));void 0!==h&&(a.anisotropy=h);b=Y.generateUUID();k[b]=a;return b}var k={},m={uuid:Y.generateUUID(),type:"MeshLambertMaterial"},l;for(l in e){var n=e[l];
-switch(l){case "DbgColor":case "DbgIndex":case "opticalDensity":case "illumination":break;case "DbgName":m.name=n;break;case "blending":m.blending=a[n];break;case "colorAmbient":case "mapAmbient":console.warn("THREE.Loader.createMaterial:",l,"is no longer supported.");break;case "colorDiffuse":m.color=b.fromArray(n).getHex();break;case "colorSpecular":m.specular=b.fromArray(n).getHex();break;case "colorEmissive":m.emissive=b.fromArray(n).getHex();break;case "specularCoef":m.shininess=n;break;case "shading":"basic"===
-n.toLowerCase()&&(m.type="MeshBasicMaterial");"phong"===n.toLowerCase()&&(m.type="MeshPhongMaterial");"standard"===n.toLowerCase()&&(m.type="MeshStandardMaterial");break;case "mapDiffuse":m.map=h(n,e.mapDiffuseRepeat,e.mapDiffuseOffset,e.mapDiffuseWrap,e.mapDiffuseAnisotropy);break;case "mapDiffuseRepeat":case "mapDiffuseOffset":case "mapDiffuseWrap":case "mapDiffuseAnisotropy":break;case "mapEmissive":m.emissiveMap=h(n,e.mapEmissiveRepeat,e.mapEmissiveOffset,e.mapEmissiveWrap,e.mapEmissiveAnisotropy);
-break;case "mapEmissiveRepeat":case "mapEmissiveOffset":case "mapEmissiveWrap":case "mapEmissiveAnisotropy":break;case "mapLight":m.lightMap=h(n,e.mapLightRepeat,e.mapLightOffset,e.mapLightWrap,e.mapLightAnisotropy);break;case "mapLightRepeat":case "mapLightOffset":case "mapLightWrap":case "mapLightAnisotropy":break;case "mapAO":m.aoMap=h(n,e.mapAORepeat,e.mapAOOffset,e.mapAOWrap,e.mapAOAnisotropy);break;case "mapAORepeat":case "mapAOOffset":case "mapAOWrap":case "mapAOAnisotropy":break;case "mapBump":m.bumpMap=
-h(n,e.mapBumpRepeat,e.mapBumpOffset,e.mapBumpWrap,e.mapBumpAnisotropy);break;case "mapBumpScale":m.bumpScale=n;break;case "mapBumpRepeat":case "mapBumpOffset":case "mapBumpWrap":case "mapBumpAnisotropy":break;case "mapNormal":m.normalMap=h(n,e.mapNormalRepeat,e.mapNormalOffset,e.mapNormalWrap,e.mapNormalAnisotropy);break;case "mapNormalFactor":m.normalScale=[n,n];break;case "mapNormalRepeat":case "mapNormalOffset":case "mapNormalWrap":case "mapNormalAnisotropy":break;case "mapSpecular":m.specularMap=
-h(n,e.mapSpecularRepeat,e.mapSpecularOffset,e.mapSpecularWrap,e.mapSpecularAnisotropy);break;case "mapSpecularRepeat":case "mapSpecularOffset":case "mapSpecularWrap":case "mapSpecularAnisotropy":break;case "mapMetalness":m.metalnessMap=h(n,e.mapMetalnessRepeat,e.mapMetalnessOffset,e.mapMetalnessWrap,e.mapMetalnessAnisotropy);break;case "mapMetalnessRepeat":case "mapMetalnessOffset":case "mapMetalnessWrap":case "mapMetalnessAnisotropy":break;case "mapRoughness":m.roughnessMap=h(n,e.mapRoughnessRepeat,
-e.mapRoughnessOffset,e.mapRoughnessWrap,e.mapRoughnessAnisotropy);break;case "mapRoughnessRepeat":case "mapRoughnessOffset":case "mapRoughnessWrap":case "mapRoughnessAnisotropy":break;case "mapAlpha":m.alphaMap=h(n,e.mapAlphaRepeat,e.mapAlphaOffset,e.mapAlphaWrap,e.mapAlphaAnisotropy);break;case "mapAlphaRepeat":case "mapAlphaOffset":case "mapAlphaWrap":case "mapAlphaAnisotropy":break;case "flipSided":m.side=1;break;case "doubleSided":m.side=2;break;case "transparency":console.warn("THREE.Loader.createMaterial: transparency has been renamed to opacity");
-m.opacity=n;break;case "depthTest":case "depthWrite":case "colorWrite":case "opacity":case "reflectivity":case "transparent":case "visible":case "wireframe":m[l]=n;break;case "vertexColors":!0===n&&(m.vertexColors=2);"face"===n&&(m.vertexColors=1);break;default:console.error("THREE.Loader.createMaterial: Unsupported",l,n)}}"MeshBasicMaterial"===m.type&&delete m.emissive;"MeshPhongMaterial"!==m.type&&delete m.specular;1>m.opacity&&(m.transparent=!0);d.setTextures(k);return d.parse(m)}}()});Object.assign(ce.prototype,
-{load:function(a,b,c,d){var e=this,f=this.texturePath&&"string"===typeof this.texturePath?this.texturePath:ec.prototype.extractUrlBase(a),g=new Ka(this.manager);g.setWithCredentials(this.withCredentials);g.load(a,function(c){c=JSON.parse(c);var d=c.metadata;if(void 0!==d&&(d=d.type,void 0!==d)){if("object"===d.toLowerCase()){console.error("THREE.JSONLoader: "+a+" should be loaded with THREE.ObjectLoader instead.");return}if("scene"===d.toLowerCase()){console.error("THREE.JSONLoader: "+a+" should be loaded with THREE.SceneLoader instead.");
-return}}c=e.parse(c,f);b(c.geometry,c.materials)},c,d)},setTexturePath:function(a){this.texturePath=a},parse:function(){return function(a,b){void 0!==a.data&&(a=a.data);a.scale=void 0!==a.scale?1/a.scale:1;var c=new J,d=a,e,f,g,h,k,m,l,v,p,r,z,t,y,x,u=d.faces;p=d.vertices;var B=d.normals,w=d.colors;m=d.scale;var I=0;if(void 0!==d.uvs){for(e=0;e<d.uvs.length;e++)d.uvs[e].length&&I++;for(e=0;e<I;e++)c.faceVertexUvs[e]=[]}h=0;for(k=p.length;h<k;)e=new n,e.x=p[h++]*m,e.y=p[h++]*m,e.z=p[h++]*m,c.vertices.push(e);
-h=0;for(k=u.length;h<k;)if(p=u[h++],r=p&1,g=p&2,e=p&8,l=p&16,z=p&32,m=p&64,p&=128,r){r=new Sa;r.a=u[h];r.b=u[h+1];r.c=u[h+3];t=new Sa;t.a=u[h+1];t.b=u[h+2];t.c=u[h+3];h+=4;g&&(g=u[h++],r.materialIndex=g,t.materialIndex=g);g=c.faces.length;if(e)for(e=0;e<I;e++)for(y=d.uvs[e],c.faceVertexUvs[e][g]=[],c.faceVertexUvs[e][g+1]=[],f=0;4>f;f++)v=u[h++],x=y[2*v],v=y[2*v+1],x=new C(x,v),2!==f&&c.faceVertexUvs[e][g].push(x),0!==f&&c.faceVertexUvs[e][g+1].push(x);l&&(l=3*u[h++],r.normal.set(B[l++],B[l++],B[l]),
-t.normal.copy(r.normal));if(z)for(e=0;4>e;e++)l=3*u[h++],z=new n(B[l++],B[l++],B[l]),2!==e&&r.vertexNormals.push(z),0!==e&&t.vertexNormals.push(z);m&&(m=u[h++],m=w[m],r.color.setHex(m),t.color.setHex(m));if(p)for(e=0;4>e;e++)m=u[h++],m=w[m],2!==e&&r.vertexColors.push(new G(m)),0!==e&&t.vertexColors.push(new G(m));c.faces.push(r);c.faces.push(t)}else{r=new Sa;r.a=u[h++];r.b=u[h++];r.c=u[h++];g&&(g=u[h++],r.materialIndex=g);g=c.faces.length;if(e)for(e=0;e<I;e++)for(y=d.uvs[e],c.faceVertexUvs[e][g]=
-[],f=0;3>f;f++)v=u[h++],x=y[2*v],v=y[2*v+1],x=new C(x,v),c.faceVertexUvs[e][g].push(x);l&&(l=3*u[h++],r.normal.set(B[l++],B[l++],B[l]));if(z)for(e=0;3>e;e++)l=3*u[h++],z=new n(B[l++],B[l++],B[l]),r.vertexNormals.push(z);m&&(m=u[h++],r.color.setHex(w[m]));if(p)for(e=0;3>e;e++)m=u[h++],r.vertexColors.push(new G(w[m]));c.faces.push(r)}d=a;h=void 0!==d.influencesPerVertex?d.influencesPerVertex:2;if(d.skinWeights)for(k=0,u=d.skinWeights.length;k<u;k+=h)c.skinWeights.push(new fa(d.skinWeights[k],1<h?d.skinWeights[k+
-1]:0,2<h?d.skinWeights[k+2]:0,3<h?d.skinWeights[k+3]:0));if(d.skinIndices)for(k=0,u=d.skinIndices.length;k<u;k+=h)c.skinIndices.push(new fa(d.skinIndices[k],1<h?d.skinIndices[k+1]:0,2<h?d.skinIndices[k+2]:0,3<h?d.skinIndices[k+3]:0));c.bones=d.bones;c.bones&&0<c.bones.length&&(c.skinWeights.length!==c.skinIndices.length||c.skinIndices.length!==c.vertices.length)&&console.warn("When skinning, number of vertices ("+c.vertices.length+"), skinIndices ("+c.skinIndices.length+"), and skinWeights ("+c.skinWeights.length+
-") should match.");k=a;u=k.scale;if(void 0!==k.morphTargets)for(d=0,h=k.morphTargets.length;d<h;d++)for(c.morphTargets[d]={},c.morphTargets[d].name=k.morphTargets[d].name,c.morphTargets[d].vertices=[],B=c.morphTargets[d].vertices,w=k.morphTargets[d].vertices,I=0,p=w.length;I<p;I+=3)m=new n,m.x=w[I]*u,m.y=w[I+1]*u,m.z=w[I+2]*u,B.push(m);if(void 0!==k.morphColors&&0<k.morphColors.length)for(console.warn('THREE.JSONLoader: "morphColors" no longer supported. Using them as face colors.'),u=c.faces,k=k.morphColors[0].colors,
-d=0,h=u.length;d<h;d++)u[d].color.fromArray(k,3*d);k=a;d=[];h=[];void 0!==k.animation&&h.push(k.animation);void 0!==k.animations&&(k.animations.length?h=h.concat(k.animations):h.push(k.animations));for(k=0;k<h.length;k++)(u=Da.parseAnimation(h[k],c.bones))&&d.push(u);c.morphTargets&&(h=Da.CreateClipsFromMorphTargetSequences(c.morphTargets,10),d=d.concat(h));0<d.length&&(c.animations=d);c.computeFaceNormals();c.computeBoundingSphere();if(void 0===a.materials||0===a.materials.length)return{geometry:c};
-d=ec.prototype.initMaterials(a.materials,b,this.crossOrigin);return{geometry:c,materials:d}}}()});Object.assign(Pe.prototype,{load:function(a,b,c,d){""===this.texturePath&&(this.texturePath=a.substring(0,a.lastIndexOf("/")+1));var e=this;(new Ka(e.manager)).load(a,function(c){var g=null;try{g=JSON.parse(c)}catch(h){void 0!==d&&d(h);console.error("THREE:ObjectLoader: Can't parse "+a+".",h.message);return}c=g.metadata;void 0===c||void 0===c.type||"geometry"===c.type.toLowerCase()?console.error("THREE.ObjectLoader: Can't load "+
-a+". Use THREE.JSONLoader instead."):e.parse(g,b)},c,d)},setTexturePath:function(a){this.texturePath=a},setCrossOrigin:function(a){this.crossOrigin=a},parse:function(a,b){var c=this.parseGeometries(a.geometries),d=this.parseImages(a.images,function(){void 0!==b&&b(e)}),d=this.parseTextures(a.textures,d),d=this.parseMaterials(a.materials,d),e=this.parseObject(a.object,c,d);a.animations&&(e.animations=this.parseAnimations(a.animations));void 0!==a.images&&0!==a.images.length||void 0===b||b(e);return e},
-parseGeometries:function(a){var b={};if(void 0!==a)for(var c=new ce,d=new be,e=0,f=a.length;e<f;e++){var g,h=a[e];switch(h.type){case "PlaneGeometry":case "PlaneBufferGeometry":g=new Ma[h.type](h.width,h.height,h.widthSegments,h.heightSegments);break;case "BoxGeometry":case "BoxBufferGeometry":case "CubeGeometry":g=new Ma[h.type](h.width,h.height,h.depth,h.widthSegments,h.heightSegments,h.depthSegments);break;case "CircleGeometry":case "CircleBufferGeometry":g=new Ma[h.type](h.radius,h.segments,h.thetaStart,
-h.thetaLength);break;case "CylinderGeometry":case "CylinderBufferGeometry":g=new Ma[h.type](h.radiusTop,h.radiusBottom,h.height,h.radialSegments,h.heightSegments,h.openEnded,h.thetaStart,h.thetaLength);break;case "ConeGeometry":case "ConeBufferGeometry":g=new Ma[h.type](h.radius,h.height,h.radialSegments,h.heightSegments,h.openEnded,h.thetaStart,h.thetaLength);break;case "SphereGeometry":case "SphereBufferGeometry":g=new Ma[h.type](h.radius,h.widthSegments,h.heightSegments,h.phiStart,h.phiLength,
-h.thetaStart,h.thetaLength);break;case "DodecahedronGeometry":case "IcosahedronGeometry":case "OctahedronGeometry":case "TetrahedronGeometry":g=new Ma[h.type](h.radius,h.detail);break;case "RingGeometry":case "RingBufferGeometry":g=new Ma[h.type](h.innerRadius,h.outerRadius,h.thetaSegments,h.phiSegments,h.thetaStart,h.thetaLength);break;case "TorusGeometry":case "TorusBufferGeometry":g=new Ma[h.type](h.radius,h.tube,h.radialSegments,h.tubularSegments,h.arc);break;case "TorusKnotGeometry":case "TorusKnotBufferGeometry":g=
-new Ma[h.type](h.radius,h.tube,h.tubularSegments,h.radialSegments,h.p,h.q);break;case "LatheGeometry":case "LatheBufferGeometry":g=new Ma[h.type](h.points,h.segments,h.phiStart,h.phiLength);break;case "BufferGeometry":g=d.parse(h);break;case "Geometry":g=c.parse(h,this.texturePath).geometry;break;default:console.warn('THREE.ObjectLoader: Unsupported geometry type "'+h.type+'"');continue}g.uuid=h.uuid;void 0!==h.name&&(g.name=h.name);b[h.uuid]=g}return b},parseMaterials:function(a,b){var c={};if(void 0!==
-a){var d=new Gd;d.setTextures(b);for(var e=0,f=a.length;e<f;e++){var g=a[e];if("MultiMaterial"===g.type){for(var h=[],k=0;k<g.materials.length;k++)h.push(d.parse(g.materials[k]));c[g.uuid]=h}else c[g.uuid]=d.parse(g)}}return c},parseAnimations:function(a){for(var b=[],c=0;c<a.length;c++){var d=Da.parse(a[c]);b.push(d)}return b},parseImages:function(a,b){function c(a){d.manager.itemStart(a);return g.load(a,function(){d.manager.itemEnd(a)},void 0,function(){d.manager.itemEnd(a);d.manager.itemError(a)})}
-var d=this,e={};if(void 0!==a&&0<a.length){var f=new Zd(b),g=new Sc(f);g.setCrossOrigin(this.crossOrigin);for(var f=0,h=a.length;f<h;f++){var k=a[f],m=/^(\/\/)|([a-z]+:(\/\/)?)/i.test(k.url)?k.url:d.texturePath+k.url;e[k.uuid]=c(m)}}return e},parseTextures:function(a,b){function c(a,b){if("number"===typeof a)return a;console.warn("THREE.ObjectLoader.parseTexture: Constant should be in numeric form.",a);return b[a]}var d={};if(void 0!==a)for(var e=0,f=a.length;e<f;e++){var g=a[e];void 0===g.image&&
-console.warn('THREE.ObjectLoader: No "image" specified for',g.uuid);void 0===b[g.image]&&console.warn("THREE.ObjectLoader: Undefined image",g.image);var h=new ba(b[g.image]);h.needsUpdate=!0;h.uuid=g.uuid;void 0!==g.name&&(h.name=g.name);void 0!==g.mapping&&(h.mapping=c(g.mapping,ng));void 0!==g.offset&&h.offset.fromArray(g.offset);void 0!==g.repeat&&h.repeat.fromArray(g.repeat);void 0!==g.wrap&&(h.wrapS=c(g.wrap[0],ff),h.wrapT=c(g.wrap[1],ff));void 0!==g.minFilter&&(h.minFilter=c(g.minFilter,gf));
-void 0!==g.magFilter&&(h.magFilter=c(g.magFilter,gf));void 0!==g.anisotropy&&(h.anisotropy=g.anisotropy);void 0!==g.flipY&&(h.flipY=g.flipY);d[g.uuid]=h}return d},parseObject:function(){var a=new K;return function(b,c,d){function e(a){void 0===c[a]&&console.warn("THREE.ObjectLoader: Undefined geometry",a);return c[a]}function f(a){if(void 0!==a){if(Array.isArray(a)){for(var b=[],c=0,e=a.length;c<e;c++){var f=a[c];void 0===d[f]&&console.warn("THREE.ObjectLoader: Undefined material",f);b.push(d[f])}return b}void 0===
-d[a]&&console.warn("THREE.ObjectLoader: Undefined material",a);return d[a]}}var g;switch(b.type){case "Scene":g=new ld;void 0!==b.background&&Number.isInteger(b.background)&&(g.background=new G(b.background));void 0!==b.fog&&("Fog"===b.fog.type?g.fog=new Jb(b.fog.color,b.fog.near,b.fog.far):"FogExp2"===b.fog.type&&(g.fog=new Ib(b.fog.color,b.fog.density)));break;case "PerspectiveCamera":g=new qa(b.fov,b.aspect,b.near,b.far);void 0!==b.focus&&(g.focus=b.focus);void 0!==b.zoom&&(g.zoom=b.zoom);void 0!==
-b.filmGauge&&(g.filmGauge=b.filmGauge);void 0!==b.filmOffset&&(g.filmOffset=b.filmOffset);void 0!==b.view&&(g.view=Object.assign({},b.view));break;case "OrthographicCamera":g=new Fb(b.left,b.right,b.top,b.bottom,b.near,b.far);break;case "AmbientLight":g=new yd(b.color,b.intensity);break;case "DirectionalLight":g=new xd(b.color,b.intensity);break;case "PointLight":g=new vd(b.color,b.intensity,b.distance,b.decay);break;case "RectAreaLight":g=new zd(b.color,b.intensity,b.width,b.height);break;case "SpotLight":g=
-new ud(b.color,b.intensity,b.distance,b.angle,b.penumbra,b.decay);break;case "HemisphereLight":g=new sd(b.color,b.groundColor,b.intensity);break;case "SkinnedMesh":console.warn("THREE.ObjectLoader.parseObject() does not support SkinnedMesh yet.");case "Mesh":g=e(b.geometry);var h=f(b.material);g=g.bones&&0<g.bones.length?new nd(g,h):new la(g,h);break;case "LOD":g=new yc;break;case "Line":g=new sa(e(b.geometry),f(b.material),b.mode);break;case "LineLoop":g=new od(e(b.geometry),f(b.material));break;
-case "LineSegments":g=new Q(e(b.geometry),f(b.material));break;case "PointCloud":case "Points":g=new Kb(e(b.geometry),f(b.material));break;case "Sprite":g=new xc(f(b.material));break;case "Group":g=new Ac;break;default:g=new z}g.uuid=b.uuid;void 0!==b.name&&(g.name=b.name);void 0!==b.matrix?(a.fromArray(b.matrix),a.decompose(g.position,g.quaternion,g.scale)):(void 0!==b.position&&g.position.fromArray(b.position),void 0!==b.rotation&&g.rotation.fromArray(b.rotation),void 0!==b.quaternion&&g.quaternion.fromArray(b.quaternion),
-void 0!==b.scale&&g.scale.fromArray(b.scale));void 0!==b.castShadow&&(g.castShadow=b.castShadow);void 0!==b.receiveShadow&&(g.receiveShadow=b.receiveShadow);b.shadow&&(void 0!==b.shadow.bias&&(g.shadow.bias=b.shadow.bias),void 0!==b.shadow.radius&&(g.shadow.radius=b.shadow.radius),void 0!==b.shadow.mapSize&&g.shadow.mapSize.fromArray(b.shadow.mapSize),void 0!==b.shadow.camera&&(g.shadow.camera=this.parseObject(b.shadow.camera)));void 0!==b.visible&&(g.visible=b.visible);void 0!==b.userData&&(g.userData=
-b.userData);if(void 0!==b.children)for(var k in b.children)g.add(this.parseObject(b.children[k],c,d));if("LOD"===b.type)for(b=b.levels,h=0;h<b.length;h++){var m=b[h];k=g.getObjectByProperty("uuid",m.object);void 0!==k&&g.addLevel(k,m.distance)}return g}}()});var ng={UVMapping:300,CubeReflectionMapping:301,CubeRefractionMapping:302,EquirectangularReflectionMapping:303,EquirectangularRefractionMapping:304,SphericalReflectionMapping:305,CubeUVReflectionMapping:306,CubeUVRefractionMapping:307},ff={RepeatWrapping:1E3,
-ClampToEdgeWrapping:1001,MirroredRepeatWrapping:1002},gf={NearestFilter:1003,NearestMipMapNearestFilter:1004,NearestMipMapLinearFilter:1005,LinearFilter:1006,LinearMipMapNearestFilter:1007,LinearMipMapLinearFilter:1008};Object.assign(ua.prototype,{getPoint:function(){console.warn("THREE.Curve: .getPoint() not implemented.");return null},getPointAt:function(a){a=this.getUtoTmapping(a);return this.getPoint(a)},getPoints:function(a){void 0===a&&(a=5);for(var b=[],c=0;c<=a;c++)b.push(this.getPoint(c/
-a));return b},getSpacedPoints:function(a){void 0===a&&(a=5);for(var b=[],c=0;c<=a;c++)b.push(this.getPointAt(c/a));return b},getLength:function(){var a=this.getLengths();return a[a.length-1]},getLengths:function(a){void 0===a&&(a=this.arcLengthDivisions);if(this.cacheArcLengths&&this.cacheArcLengths.length===a+1&&!this.needsUpdate)return this.cacheArcLengths;this.needsUpdate=!1;var b=[],c,d=this.getPoint(0),e,f=0;b.push(0);for(e=1;e<=a;e++)c=this.getPoint(e/a),f+=c.distanceTo(d),b.push(f),d=c;return this.cacheArcLengths=
-b},updateArcLengths:function(){this.needsUpdate=!0;this.getLengths()},getUtoTmapping:function(a,b){var c=this.getLengths(),d,e=c.length,f;f=b?b:a*c[e-1];for(var g=0,h=e-1,k;g<=h;)if(d=Math.floor(g+(h-g)/2),k=c[d]-f,0>k)g=d+1;else if(0<k)h=d-1;else{h=d;break}d=h;if(c[d]===f)return d/(e-1);g=c[d];return(d+(f-g)/(c[d+1]-g))/(e-1)},getTangent:function(a){var b=a-1E-4;a+=1E-4;0>b&&(b=0);1<a&&(a=1);b=this.getPoint(b);return this.getPoint(a).clone().sub(b).normalize()},getTangentAt:function(a){a=this.getUtoTmapping(a);
-return this.getTangent(a)},computeFrenetFrames:function(a,b){var c=new n,d=[],e=[],f=[],g=new n,h=new K,k,m;for(k=0;k<=a;k++)m=k/a,d[k]=this.getTangentAt(m),d[k].normalize();e[0]=new n;f[0]=new n;k=Number.MAX_VALUE;m=Math.abs(d[0].x);var l=Math.abs(d[0].y),v=Math.abs(d[0].z);m<=k&&(k=m,c.set(1,0,0));l<=k&&(k=l,c.set(0,1,0));v<=k&&c.set(0,0,1);g.crossVectors(d[0],c).normalize();e[0].crossVectors(d[0],g);f[0].crossVectors(d[0],e[0]);for(k=1;k<=a;k++)e[k]=e[k-1].clone(),f[k]=f[k-1].clone(),g.crossVectors(d[k-
-1],d[k]),g.length()>Number.EPSILON&&(g.normalize(),c=Math.acos(Y.clamp(d[k-1].dot(d[k]),-1,1)),e[k].applyMatrix4(h.makeRotationAxis(g,c))),f[k].crossVectors(d[k],e[k]);if(!0===b)for(c=Math.acos(Y.clamp(e[0].dot(e[a]),-1,1)),c/=a,0<d[0].dot(g.crossVectors(e[0],e[a]))&&(c=-c),k=1;k<=a;k++)e[k].applyMatrix4(h.makeRotationAxis(d[k],c*k)),f[k].crossVectors(d[k],e[k]);return{tangents:d,normals:e,binormals:f}}});Qa.prototype=Object.create(ua.prototype);Qa.prototype.constructor=Qa;Qa.prototype.isLineCurve=
-!0;Qa.prototype.getPoint=function(a){if(1===a)return this.v2.clone();var b=this.v2.clone().sub(this.v1);b.multiplyScalar(a).add(this.v1);return b};Qa.prototype.getPointAt=function(a){return this.getPoint(a)};Qa.prototype.getTangent=function(a){return this.v2.clone().sub(this.v1).normalize()};Vc.prototype=Object.assign(Object.create(ua.prototype),{constructor:Vc,add:function(a){this.curves.push(a)},closePath:function(){var a=this.curves[0].getPoint(0),b=this.curves[this.curves.length-1].getPoint(1);
-a.equals(b)||this.curves.push(new Qa(b,a))},getPoint:function(a){var b=a*this.getLength(),c=this.getCurveLengths();for(a=0;a<c.length;){if(c[a]>=b)return b=c[a]-b,a=this.curves[a],c=a.getLength(),a.getPointAt(0===c?0:1-b/c);a++}return null},getLength:function(){var a=this.getCurveLengths();return a[a.length-1]},updateArcLengths:function(){this.needsUpdate=!0;this.cacheLengths=null;this.getCurveLengths()},getCurveLengths:function(){if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths;
-for(var a=[],b=0,c=0,d=this.curves.length;c<d;c++)b+=this.curves[c].getLength(),a.push(b);return this.cacheLengths=a},getSpacedPoints:function(a){void 0===a&&(a=40);for(var b=[],c=0;c<=a;c++)b.push(this.getPoint(c/a));this.autoClose&&b.push(b[0]);return b},getPoints:function(a){a=a||12;for(var b=[],c,d=0,e=this.curves;d<e.length;d++)for(var f=e[d],f=f.getPoints(f&&f.isEllipseCurve?2*a:f&&f.isLineCurve?1:f&&f.isSplineCurve?a*f.points.length:a),g=0;g<f.length;g++){var h=f[g];c&&c.equals(h)||(b.push(h),
-c=h)}this.autoClose&&1<b.length&&!b[b.length-1].equals(b[0])&&b.push(b[0]);return b},createPointsGeometry:function(a){a=this.getPoints(a);return this.createGeometry(a)},createSpacedPointsGeometry:function(a){a=this.getSpacedPoints(a);return this.createGeometry(a)},createGeometry:function(a){for(var b=new J,c=0,d=a.length;c<d;c++){var e=a[c];b.vertices.push(new n(e.x,e.y,e.z||0))}return b}});Va.prototype=Object.create(ua.prototype);Va.prototype.constructor=Va;Va.prototype.isEllipseCurve=!0;Va.prototype.getPoint=
-function(a){for(var b=2*Math.PI,c=this.aEndAngle-this.aStartAngle,d=Math.abs(c)<Number.EPSILON;0>c;)c+=b;for(;c>b;)c-=b;c<Number.EPSILON&&(c=d?0:b);!0!==this.aClockwise||d||(c=c===b?-b:c-b);b=this.aStartAngle+a*c;a=this.aX+this.xRadius*Math.cos(b);var e=this.aY+this.yRadius*Math.sin(b);0!==this.aRotation&&(b=Math.cos(this.aRotation),c=Math.sin(this.aRotation),d=a-this.aX,e-=this.aY,a=d*b-e*c+this.aX,e=d*c+e*b+this.aY);return new C(a,e)};yb.prototype=Object.create(ua.prototype);yb.prototype.constructor=
-yb;yb.prototype.isSplineCurve=!0;yb.prototype.getPoint=function(a){var b=this.points,c=(b.length-1)*a;a=Math.floor(c);var c=c-a,d=b[0===a?a:a-1],e=b[a],f=b[a>b.length-2?b.length-1:a+1],b=b[a>b.length-3?b.length-1:a+2];return new C(Qe(c,d.x,e.x,f.x,b.x),Qe(c,d.y,e.y,f.y,b.y))};fc.prototype=Object.create(ua.prototype);fc.prototype.constructor=fc;fc.prototype.getPoint=function(a){var b=this.v0,c=this.v1,d=this.v2,e=this.v3;return new C(xb(a,b.x,c.x,d.x,e.x),xb(a,b.y,c.y,d.y,e.y))};gc.prototype=Object.create(ua.prototype);
-gc.prototype.constructor=gc;gc.prototype.getPoint=function(a){var b=this.v0,c=this.v1,d=this.v2;return new C(wb(a,b.x,c.x,d.x),wb(a,b.y,c.y,d.y))};var te=Object.assign(Object.create(Vc.prototype),{fromPoints:function(a){this.moveTo(a[0].x,a[0].y);for(var b=1,c=a.length;b<c;b++)this.lineTo(a[b].x,a[b].y)},moveTo:function(a,b){this.currentPoint.set(a,b)},lineTo:function(a,b){var c=new Qa(this.currentPoint.clone(),new C(a,b));this.curves.push(c);this.currentPoint.set(a,b)},quadraticCurveTo:function(a,
-b,c,d){a=new gc(this.currentPoint.clone(),new C(a,b),new C(c,d));this.curves.push(a);this.currentPoint.set(c,d)},bezierCurveTo:function(a,b,c,d,e,f){a=new fc(this.currentPoint.clone(),new C(a,b),new C(c,d),new C(e,f));this.curves.push(a);this.currentPoint.set(e,f)},splineThru:function(a){var b=[this.currentPoint.clone()].concat(a),b=new yb(b);this.curves.push(b);this.currentPoint.copy(a[a.length-1])},arc:function(a,b,c,d,e,f){this.absarc(a+this.currentPoint.x,b+this.currentPoint.y,c,d,e,f)},absarc:function(a,
-b,c,d,e,f){this.absellipse(a,b,c,c,d,e,f)},ellipse:function(a,b,c,d,e,f,g,h){this.absellipse(a+this.currentPoint.x,b+this.currentPoint.y,c,d,e,f,g,h)},absellipse:function(a,b,c,d,e,f,g,h){a=new Va(a,b,c,d,e,f,g,h);0<this.curves.length&&(b=a.getPoint(0),b.equals(this.currentPoint)||this.lineTo(b.x,b.y));this.curves.push(a);a=a.getPoint(1);this.currentPoint.copy(a)}});Wc.prototype=te;te.constructor=Wc;zb.prototype=Object.assign(Object.create(te),{constructor:zb,getPointsHoles:function(a){for(var b=
-[],c=0,d=this.holes.length;c<d;c++)b[c]=this.holes[c].getPoints(a);return b},extractAllPoints:function(a){return{shape:this.getPoints(a),holes:this.getPointsHoles(a)}},extractPoints:function(a){return this.extractAllPoints(a)}});Object.assign(de.prototype,{moveTo:function(a,b){this.currentPath=new Wc;this.subPaths.push(this.currentPath);this.currentPath.moveTo(a,b)},lineTo:function(a,b){this.currentPath.lineTo(a,b)},quadraticCurveTo:function(a,b,c,d){this.currentPath.quadraticCurveTo(a,b,c,d)},bezierCurveTo:function(a,
-b,c,d,e,f){this.currentPath.bezierCurveTo(a,b,c,d,e,f)},splineThru:function(a){this.currentPath.splineThru(a)},toShapes:function(a,b){function c(a){for(var b=[],c=0,d=a.length;c<d;c++){var e=a[c],f=new zb;f.curves=e.curves;b.push(f)}return b}function d(a,b){for(var c=b.length,d=!1,e=c-1,f=0;f<c;e=f++){var g=b[e],h=b[f],k=h.x-g.x,m=h.y-g.y;if(Math.abs(m)>Number.EPSILON){if(0>m&&(g=b[f],k=-k,h=b[e],m=-m),!(a.y<g.y||a.y>h.y))if(a.y===g.y){if(a.x===g.x)return!0}else{e=m*(a.x-g.x)-k*(a.y-g.y);if(0===e)return!0;
-0>e||(d=!d)}}else if(a.y===g.y&&(h.x<=a.x&&a.x<=g.x||g.x<=a.x&&a.x<=h.x))return!0}return d}var e=Ia.isClockWise,f=this.subPaths;if(0===f.length)return[];if(!0===b)return c(f);var g,h,k,m=[];if(1===f.length)return h=f[0],k=new zb,k.curves=h.curves,m.push(k),m;var l=!e(f[0].getPoints()),l=a?!l:l;k=[];var n=[],p=[],r=0,z;n[r]=void 0;p[r]=[];for(var t=0,y=f.length;t<y;t++)h=f[t],z=h.getPoints(),g=e(z),(g=a?!g:g)?(!l&&n[r]&&r++,n[r]={s:new zb,p:z},n[r].s.curves=h.curves,l&&r++,p[r]=[]):p[r].push({h:h,
-p:z[0]});if(!n[0])return c(f);if(1<n.length){t=!1;h=[];e=0;for(f=n.length;e<f;e++)k[e]=[];e=0;for(f=n.length;e<f;e++)for(g=p[e],l=0;l<g.length;l++){r=g[l];z=!0;for(y=0;y<n.length;y++)d(r.p,n[y].p)&&(e!==y&&h.push({froms:e,tos:y,hole:l}),z?(z=!1,k[y].push(r)):t=!0);z&&k[e].push(r)}0<h.length&&(t||(p=k))}t=0;for(e=n.length;t<e;t++)for(k=n[t].s,m.push(k),h=p[t],f=0,g=h.length;f<g;f++)k.holes.push(h[f].h);return m}});Object.assign(ee.prototype,{isFont:!0,generateShapes:function(a,b,c){void 0===b&&(b=
-100);void 0===c&&(c=4);var d=this.data;a=String(a).split("");var e=b/d.resolution,f=(d.boundingBox.yMax-d.boundingBox.yMin+d.underlineThickness)*e,g=0,h=0;b=[];for(var k=0;k<a.length;k++){var m=a[k];if("\n"===m)g=0,h-=f;else{var l;l=e;var n=g,p=h;if(m=d.glyphs[m]||d.glyphs["?"]){var r=new de,z=[],t,y,x,u,B,w,C,G;if(m.o)for(var D=m._cachedOutline||(m._cachedOutline=m.o.split(" ")),E=0,J=D.length;E<J;)switch(D[E++]){case "m":t=D[E++]*l+n;y=D[E++]*l+p;r.moveTo(t,y);break;case "l":t=D[E++]*l+n;y=D[E++]*
-l+p;r.lineTo(t,y);break;case "q":t=D[E++]*l+n;y=D[E++]*l+p;B=D[E++]*l+n;w=D[E++]*l+p;r.quadraticCurveTo(B,w,t,y);if(u=z[z.length-1]){x=u.x;u=u.y;for(var F=1;F<=c;F++){var K=F/c;wb(K,x,B,t);wb(K,u,w,y)}}break;case "b":if(t=D[E++]*l+n,y=D[E++]*l+p,B=D[E++]*l+n,w=D[E++]*l+p,C=D[E++]*l+n,G=D[E++]*l+p,r.bezierCurveTo(B,w,C,G,t,y),u=z[z.length-1])for(x=u.x,u=u.y,F=1;F<=c;F++)K=F/c,xb(K,x,B,C,t),xb(K,u,w,G,y)}l={offsetX:m.ha*l,path:r}}else l=void 0;g+=l.offsetX;b.push(l.path)}}c=[];d=0;for(a=b.length;d<
-a;d++)Array.prototype.push.apply(c,b[d].toShapes());return c}});Object.assign(Re.prototype,{load:function(a,b,c,d){var e=this;(new Ka(this.manager)).load(a,function(a){var c;try{c=JSON.parse(a)}catch(d){console.warn("THREE.FontLoader: typeface.js support is being deprecated. Use typeface.json instead."),c=JSON.parse(a.substring(65,a.length-2))}a=e.parse(c);b&&b(a)},c,d)},parse:function(a){return new ee(a)}});var Nd,he={getContext:function(){void 0===Nd&&(Nd=new (window.AudioContext||window.webkitAudioContext));
-return Nd},setContext:function(a){Nd=a}};Object.assign(fe.prototype,{load:function(a,b,c,d){var e=new Ka(this.manager);e.setResponseType("arraybuffer");e.load(a,function(a){he.getContext().decodeAudioData(a,function(a){b(a)})},c,d)}});Object.assign(Se.prototype,{update:function(){var a,b,c,d,e,f,g,h,k=new K,m=new K;return function(l){if(a!==this||b!==l.focus||c!==l.fov||d!==l.aspect*this.aspect||e!==l.near||f!==l.far||g!==l.zoom||h!==this.eyeSep){a=this;b=l.focus;c=l.fov;d=l.aspect*this.aspect;e=
-l.near;f=l.far;g=l.zoom;var n=l.projectionMatrix.clone();h=this.eyeSep/2;var p=h*e/b,r=e*Math.tan(Y.DEG2RAD*c*.5)/g,z,t;m.elements[12]=-h;k.elements[12]=h;z=-r*d+p;t=r*d+p;n.elements[0]=2*e/(t-z);n.elements[8]=(t+z)/(t-z);this.cameraL.projectionMatrix.copy(n);z=-r*d-p;t=r*d-p;n.elements[0]=2*e/(t-z);n.elements[8]=(t+z)/(t-z);this.cameraR.projectionMatrix.copy(n)}this.cameraL.matrixWorld.copy(l.matrixWorld).multiply(m);this.cameraR.matrixWorld.copy(l.matrixWorld).multiply(k)}}()});Hd.prototype=Object.create(z.prototype);
-Hd.prototype.constructor=Hd;ge.prototype=Object.assign(Object.create(z.prototype),{constructor:ge,getInput:function(){return this.gain},removeFilter:function(){null!==this.filter&&(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination),this.gain.connect(this.context.destination),this.filter=null)},getFilter:function(){return this.filter},setFilter:function(a){null!==this.filter?(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination)):this.gain.disconnect(this.context.destination);
-this.filter=a;this.gain.connect(this.filter);this.filter.connect(this.context.destination)},getMasterVolume:function(){return this.gain.gain.value},setMasterVolume:function(a){this.gain.gain.value=a},updateMatrixWorld:function(){var a=new n,b=new oa,c=new n,d=new n;return function(e){z.prototype.updateMatrixWorld.call(this,e);e=this.context.listener;var f=this.up;this.matrixWorld.decompose(a,b,c);d.set(0,0,-1).applyQuaternion(b);e.positionX?(e.positionX.setValueAtTime(a.x,this.context.currentTime),
-e.positionY.setValueAtTime(a.y,this.context.currentTime),e.positionZ.setValueAtTime(a.z,this.context.currentTime),e.forwardX.setValueAtTime(d.x,this.context.currentTime),e.forwardY.setValueAtTime(d.y,this.context.currentTime),e.forwardZ.setValueAtTime(d.z,this.context.currentTime),e.upX.setValueAtTime(f.x,this.context.currentTime),e.upY.setValueAtTime(f.y,this.context.currentTime),e.upZ.setValueAtTime(f.z,this.context.currentTime)):(e.setPosition(a.x,a.y,a.z),e.setOrientation(d.x,d.y,d.z,f.x,f.y,
-f.z))}}()});hc.prototype=Object.assign(Object.create(z.prototype),{constructor:hc,getOutput:function(){return this.gain},setNodeSource:function(a){this.hasPlaybackControl=!1;this.sourceType="audioNode";this.source=a;this.connect();return this},setBuffer:function(a){this.buffer=a;this.sourceType="buffer";this.autoplay&&this.play();return this},play:function(){if(!0===this.isPlaying)console.warn("THREE.Audio: Audio is already playing.");else if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");
-else{var a=this.context.createBufferSource();a.buffer=this.buffer;a.loop=this.loop;a.onended=this.onEnded.bind(this);a.playbackRate.setValueAtTime(this.playbackRate,this.startTime);a.start(0,this.startTime);this.isPlaying=!0;this.source=a;return this.connect()}},pause:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else return this.source.stop(),this.startTime=this.context.currentTime,this.isPlaying=!1,this},stop:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");
-else return this.source.stop(),this.startTime=0,this.isPlaying=!1,this},connect:function(){if(0<this.filters.length){this.source.connect(this.filters[0]);for(var a=1,b=this.filters.length;a<b;a++)this.filters[a-1].connect(this.filters[a]);this.filters[this.filters.length-1].connect(this.getOutput())}else this.source.connect(this.getOutput());return this},disconnect:function(){if(0<this.filters.length){this.source.disconnect(this.filters[0]);for(var a=1,b=this.filters.length;a<b;a++)this.filters[a-
-1].disconnect(this.filters[a]);this.filters[this.filters.length-1].disconnect(this.getOutput())}else this.source.disconnect(this.getOutput());return this},getFilters:function(){return this.filters},setFilters:function(a){a||(a=[]);!0===this.isPlaying?(this.disconnect(),this.filters=a,this.connect()):this.filters=a;return this},getFilter:function(){return this.getFilters()[0]},setFilter:function(a){return this.setFilters(a?[a]:[])},setPlaybackRate:function(a){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");
-else return this.playbackRate=a,!0===this.isPlaying&&this.source.playbackRate.setValueAtTime(this.playbackRate,this.context.currentTime),this},getPlaybackRate:function(){return this.playbackRate},onEnded:function(){this.isPlaying=!1},getLoop:function(){return!1===this.hasPlaybackControl?(console.warn("THREE.Audio: this Audio has no playback control."),!1):this.loop},setLoop:function(a){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else return this.loop=
-a,!0===this.isPlaying&&(this.source.loop=this.loop),this},getVolume:function(){return this.gain.gain.value},setVolume:function(a){this.gain.gain.value=a;return this}});ie.prototype=Object.assign(Object.create(hc.prototype),{constructor:ie,getOutput:function(){return this.panner},getRefDistance:function(){return this.panner.refDistance},setRefDistance:function(a){this.panner.refDistance=a},getRolloffFactor:function(){return this.panner.rolloffFactor},setRolloffFactor:function(a){this.panner.rolloffFactor=
-a},getDistanceModel:function(){return this.panner.distanceModel},setDistanceModel:function(a){this.panner.distanceModel=a},getMaxDistance:function(){return this.panner.maxDistance},setMaxDistance:function(a){this.panner.maxDistance=a},updateMatrixWorld:function(){var a=new n;return function(b){z.prototype.updateMatrixWorld.call(this,b);a.setFromMatrixPosition(this.matrixWorld);this.panner.setPosition(a.x,a.y,a.z)}}()});Object.assign(je.prototype,{getFrequencyData:function(){this.analyser.getByteFrequencyData(this.data);
-return this.data},getAverageFrequency:function(){for(var a=0,b=this.getFrequencyData(),c=0;c<b.length;c++)a+=b[c];return a/b.length}});Object.assign(ke.prototype,{accumulate:function(a,b){var c=this.buffer,d=this.valueSize,e=a*d+d,f=this.cumulativeWeight;if(0===f){for(f=0;f!==d;++f)c[e+f]=c[f];f=b}else f+=b,this._mixBufferRegion(c,e,0,b/f,d);this.cumulativeWeight=f},apply:function(a){var b=this.valueSize,c=this.buffer;a=a*b+b;var d=this.cumulativeWeight,e=this.binding;this.cumulativeWeight=0;1>d&&
-this._mixBufferRegion(c,a,3*b,1-d,b);for(var d=b,f=b+b;d!==f;++d)if(c[d]!==c[d+b]){e.setValue(c,a);break}},saveOriginalState:function(){var a=this.buffer,b=this.valueSize,c=3*b;this.binding.getValue(a,c);for(var d=b;d!==c;++d)a[d]=a[c+d%b];this.cumulativeWeight=0},restoreOriginalState:function(){this.binding.setValue(this.buffer,3*this.valueSize)},_select:function(a,b,c,d,e){if(.5<=d)for(d=0;d!==e;++d)a[b+d]=a[c+d]},_slerp:function(a,b,c,d){oa.slerpFlat(a,b,a,b,a,c,d)},_lerp:function(a,b,c,d,e){for(var f=
-1-d,g=0;g!==e;++g){var h=b+g;a[h]=a[h]*f+a[c+g]*d}}});Object.assign(Te.prototype,{getValue:function(a,b){this.bind();var c=this._bindings[this._targetGroup.nCachedObjects_];void 0!==c&&c.getValue(a,b)},setValue:function(a,b){for(var c=this._bindings,d=this._targetGroup.nCachedObjects_,e=c.length;d!==e;++d)c[d].setValue(a,b)},bind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_,c=a.length;b!==c;++b)a[b].bind()},unbind:function(){for(var a=this._bindings,b=this._targetGroup.nCachedObjects_,
-c=a.length;b!==c;++b)a[b].unbind()}});Object.assign(ha,{Composite:Te,create:function(a,b,c){return a&&a.isAnimationObjectGroup?new ha.Composite(a,b,c):new ha(a,b,c)},sanitizeNodeName:function(a){return a.replace(/\s/g,"_").replace(/[^\w-]/g,"")},parseTrackName:function(){var a=new RegExp("^"+/((?:[\w-]+[\/:])*)/.source+/([\w-\.]+)?/.source+/(?:\.([\w-]+)(?:\[(.+)\])?)?/.source+/\.([\w-]+)(?:\[(.+)\])?/.source+"$"),b=["material","materials","bones"];return function(c){var d=a.exec(c);if(!d)throw Error("PropertyBinding: Cannot parse trackName: "+
-c);var d={nodeName:d[2],objectName:d[3],objectIndex:d[4],propertyName:d[5],propertyIndex:d[6]},e=d.nodeName&&d.nodeName.lastIndexOf(".");if(void 0!==e&&-1!==e){var f=d.nodeName.substring(e+1);-1!==b.indexOf(f)&&(d.nodeName=d.nodeName.substring(0,e),d.objectName=f)}if(null===d.propertyName||0===d.propertyName.length)throw Error("PropertyBinding: can not parse propertyName from trackName: "+c);return d}}(),findNode:function(a,b){if(!b||""===b||"root"===b||"."===b||-1===b||b===a.name||b===a.uuid)return a;
-if(a.skeleton){var c=function(a){for(var c=0;c<a.bones.length;c++){var d=a.bones[c];if(d.name===b)return d}return null}(a.skeleton);if(c)return c}if(a.children){var d=function(a){for(var c=0;c<a.length;c++){var g=a[c];if(g.name===b||g.uuid===b||(g=d(g.children)))return g}return null};if(c=d(a.children))return c}return null}});Object.assign(ha.prototype,{_getValue_unavailable:function(){},_setValue_unavailable:function(){},BindingType:{Direct:0,EntireArray:1,ArrayElement:2,HasFromToArray:3},Versioning:{None:0,
-NeedsUpdate:1,MatrixWorldNeedsUpdate:2},GetterByBindingType:[function(a,b){a[b]=this.node[this.propertyName]},function(a,b){for(var c=this.resolvedProperty,d=0,e=c.length;d!==e;++d)a[b++]=c[d]},function(a,b){a[b]=this.resolvedProperty[this.propertyIndex]},function(a,b){this.resolvedProperty.toArray(a,b)}],SetterByBindingTypeAndVersioning:[[function(a,b){this.node[this.propertyName]=a[b]},function(a,b){this.node[this.propertyName]=a[b];this.targetObject.needsUpdate=!0},function(a,b){this.node[this.propertyName]=
-a[b];this.targetObject.matrixWorldNeedsUpdate=!0}],[function(a,b){for(var c=this.resolvedProperty,d=0,e=c.length;d!==e;++d)c[d]=a[b++]},function(a,b){for(var c=this.resolvedProperty,d=0,e=c.length;d!==e;++d)c[d]=a[b++];this.targetObject.needsUpdate=!0},function(a,b){for(var c=this.resolvedProperty,d=0,e=c.length;d!==e;++d)c[d]=a[b++];this.targetObject.matrixWorldNeedsUpdate=!0}],[function(a,b){this.resolvedProperty[this.propertyIndex]=a[b]},function(a,b){this.resolvedProperty[this.propertyIndex]=
-a[b];this.targetObject.needsUpdate=!0},function(a,b){this.resolvedProperty[this.propertyIndex]=a[b];this.targetObject.matrixWorldNeedsUpdate=!0}],[function(a,b){this.resolvedProperty.fromArray(a,b)},function(a,b){this.resolvedProperty.fromArray(a,b);this.targetObject.needsUpdate=!0},function(a,b){this.resolvedProperty.fromArray(a,b);this.targetObject.matrixWorldNeedsUpdate=!0}]],getValue:function(a,b){this.bind();this.getValue(a,b)},setValue:function(a,b){this.bind();this.setValue(a,b)},bind:function(){var a=
-this.node,b=this.parsedPath,c=b.objectName,d=b.propertyName,e=b.propertyIndex;a||(this.node=a=ha.findNode(this.rootNode,b.nodeName)||this.rootNode);this.getValue=this._getValue_unavailable;this.setValue=this._setValue_unavailable;if(a){if(c){var f=b.objectIndex;switch(c){case "materials":if(!a.material){console.error("THREE.PropertyBinding: Can not bind to material as node does not have a material.",this);return}if(!a.material.materials){console.error("THREE.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.",
-this);return}a=a.material.materials;break;case "bones":if(!a.skeleton){console.error("THREE.PropertyBinding: Can not bind to bones as node does not have a skeleton.",this);return}a=a.skeleton.bones;for(c=0;c<a.length;c++)if(a[c].name===f){f=c;break}break;default:if(void 0===a[c]){console.error("THREE.PropertyBinding: Can not bind to objectName of node undefined.",this);return}a=a[c]}if(void 0!==f){if(void 0===a[f]){console.error("THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.",
-this,a);return}a=a[f]}}f=a[d];if(void 0===f)console.error("THREE.PropertyBinding: Trying to update property for track: "+b.nodeName+"."+d+" but it wasn't found.",a);else{b=this.Versioning.None;void 0!==a.needsUpdate?(b=this.Versioning.NeedsUpdate,this.targetObject=a):void 0!==a.matrixWorldNeedsUpdate&&(b=this.Versioning.MatrixWorldNeedsUpdate,this.targetObject=a);c=this.BindingType.Direct;if(void 0!==e){if("morphTargetInfluences"===d){if(!a.geometry){console.error("THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.",
-this);return}if(a.geometry.isBufferGeometry){if(!a.geometry.morphAttributes){console.error("THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.",this);return}for(c=0;c<this.node.geometry.morphAttributes.position.length;c++)if(a.geometry.morphAttributes.position[c].name===e){e=c;break}}else{if(!a.geometry.morphTargets){console.error("THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphTargets.",
-this);return}for(c=0;c<this.node.geometry.morphTargets.length;c++)if(a.geometry.morphTargets[c].name===e){e=c;break}}}c=this.BindingType.ArrayElement;this.resolvedProperty=f;this.propertyIndex=e}else void 0!==f.fromArray&&void 0!==f.toArray?(c=this.BindingType.HasFromToArray,this.resolvedProperty=f):Array.isArray(f)?(c=this.BindingType.EntireArray,this.resolvedProperty=f):this.propertyName=d;this.getValue=this.GetterByBindingType[c];this.setValue=this.SetterByBindingTypeAndVersioning[c][b]}}else console.error("THREE.PropertyBinding: Trying to update node for track: "+
-this.path+" but it wasn't found.")},unbind:function(){this.node=null;this.getValue=this._getValue_unbound;this.setValue=this._setValue_unbound}});Object.assign(ha.prototype,{_getValue_unbound:ha.prototype.getValue,_setValue_unbound:ha.prototype.setValue});Object.assign(Ue.prototype,{isAnimationObjectGroup:!0,add:function(a){for(var b=this._objects,c=b.length,d=this.nCachedObjects_,e=this._indicesByUUID,f=this._paths,g=this._parsedPaths,h=this._bindings,k=h.length,m=0,l=arguments.length;m!==l;++m){var n=
-arguments[m],p=n.uuid,r=e[p];if(void 0===r){r=c++;e[p]=r;b.push(n);for(var p=0,z=k;p!==z;++p)h[p].push(new ha(n,f[p],g[p]))}else if(r<d){var t=--d,z=b[t];e[z.uuid]=r;b[r]=z;e[p]=t;b[t]=n;p=0;for(z=k;p!==z;++p){var y=h[p],x=y[r];y[r]=y[t];void 0===x&&(x=new ha(n,f[p],g[p]));y[t]=x}}else void 0!==b[r]&&console.error("THREE.AnimationObjectGroup: Different objects with the same UUID detected. Clean the caches or recreate your infrastructure when reloading scenes.")}this.nCachedObjects_=d},remove:function(a){for(var b=
-this._objects,c=this.nCachedObjects_,d=this._indicesByUUID,e=this._bindings,f=e.length,g=0,h=arguments.length;g!==h;++g){var k=arguments[g],m=k.uuid,l=d[m];if(void 0!==l&&l>=c){var n=c++,p=b[n];d[p.uuid]=l;b[l]=p;d[m]=n;b[n]=k;k=0;for(m=f;k!==m;++k){var p=e[k],r=p[l];p[l]=p[n];p[n]=r}}}this.nCachedObjects_=c},uncache:function(a){for(var b=this._objects,c=b.length,d=this.nCachedObjects_,e=this._indicesByUUID,f=this._bindings,g=f.length,h=0,k=arguments.length;h!==k;++h){var l=arguments[h].uuid,n=e[l];
-if(void 0!==n)if(delete e[l],n<d){var l=--d,v=b[l],p=--c,r=b[p];e[v.uuid]=n;b[n]=v;e[r.uuid]=l;b[l]=r;b.pop();v=0;for(r=g;v!==r;++v){var z=f[v],t=z[p];z[n]=z[l];z[l]=t;z.pop()}}else for(p=--c,r=b[p],e[r.uuid]=n,b[n]=r,b.pop(),v=0,r=g;v!==r;++v)z=f[v],z[n]=z[p],z.pop()}this.nCachedObjects_=d},subscribe_:function(a,b){var c=this._bindingsIndicesByPath,d=c[a],e=this._bindings;if(void 0!==d)return e[d];var f=this._paths,g=this._parsedPaths,h=this._objects,k=this.nCachedObjects_,l=Array(h.length),d=e.length;
-c[a]=d;f.push(a);g.push(b);e.push(l);c=k;for(d=h.length;c!==d;++c)l[c]=new ha(h[c],a,b);return l},unsubscribe_:function(a){var b=this._bindingsIndicesByPath,c=b[a];if(void 0!==c){var d=this._paths,e=this._parsedPaths,f=this._bindings,g=f.length-1,h=f[g];b[a[g]]=c;f[c]=h;f.pop();e[c]=e[g];e.pop();d[c]=d[g];d.pop()}}});Object.assign(Ve.prototype,{play:function(){this._mixer._activateAction(this);return this},stop:function(){this._mixer._deactivateAction(this);return this.reset()},reset:function(){this.paused=
-!1;this.enabled=!0;this.time=0;this._loopCount=-1;this._startTime=null;return this.stopFading().stopWarping()},isRunning:function(){return this.enabled&&!this.paused&&0!==this.timeScale&&null===this._startTime&&this._mixer._isActiveAction(this)},isScheduled:function(){return this._mixer._isActiveAction(this)},startAt:function(a){this._startTime=a;return this},setLoop:function(a,b){this.loop=a;this.repetitions=b;return this},setEffectiveWeight:function(a){this.weight=a;this._effectiveWeight=this.enabled?
-a:0;return this.stopFading()},getEffectiveWeight:function(){return this._effectiveWeight},fadeIn:function(a){return this._scheduleFading(a,0,1)},fadeOut:function(a){return this._scheduleFading(a,1,0)},crossFadeFrom:function(a,b,c){a.fadeOut(b);this.fadeIn(b);if(c){c=this._clip.duration;var d=a._clip.duration,e=c/d;a.warp(1,d/c,b);this.warp(e,1,b)}return this},crossFadeTo:function(a,b,c){return a.crossFadeFrom(this,b,c)},stopFading:function(){var a=this._weightInterpolant;null!==a&&(this._weightInterpolant=
-null,this._mixer._takeBackControlInterpolant(a));return this},setEffectiveTimeScale:function(a){this.timeScale=a;this._effectiveTimeScale=this.paused?0:a;return this.stopWarping()},getEffectiveTimeScale:function(){return this._effectiveTimeScale},setDuration:function(a){this.timeScale=this._clip.duration/a;return this.stopWarping()},syncWith:function(a){this.time=a.time;this.timeScale=a.timeScale;return this.stopWarping()},halt:function(a){return this.warp(this._effectiveTimeScale,0,a)},warp:function(a,
-b,c){var d=this._mixer,e=d.time,f=this._timeScaleInterpolant,g=this.timeScale;null===f&&(this._timeScaleInterpolant=f=d._lendControlInterpolant());d=f.parameterPositions;f=f.sampleValues;d[0]=e;d[1]=e+c;f[0]=a/g;f[1]=b/g;return this},stopWarping:function(){var a=this._timeScaleInterpolant;null!==a&&(this._timeScaleInterpolant=null,this._mixer._takeBackControlInterpolant(a));return this},getMixer:function(){return this._mixer},getClip:function(){return this._clip},getRoot:function(){return this._localRoot||
-this._mixer._root},_update:function(a,b,c,d){if(this.enabled){var e=this._startTime;if(null!==e){b=(a-e)*c;if(0>b||0===c)return;this._startTime=null;b*=c}b*=this._updateTimeScale(a);c=this._updateTime(b);a=this._updateWeight(a);if(0<a){b=this._interpolants;for(var e=this._propertyBindings,f=0,g=b.length;f!==g;++f)b[f].evaluate(c),e[f].accumulate(d,a)}}else this._updateWeight(a)},_updateWeight:function(a){var b=0;if(this.enabled){var b=this.weight,c=this._weightInterpolant;if(null!==c){var d=c.evaluate(a)[0],
-b=b*d;a>c.parameterPositions[1]&&(this.stopFading(),0===d&&(this.enabled=!1))}}return this._effectiveWeight=b},_updateTimeScale:function(a){var b=0;if(!this.paused){var b=this.timeScale,c=this._timeScaleInterpolant;if(null!==c){var d=c.evaluate(a)[0],b=b*d;a>c.parameterPositions[1]&&(this.stopWarping(),0===b?this.paused=!0:this.timeScale=b)}}return this._effectiveTimeScale=b},_updateTime:function(a){var b=this.time+a;if(0===a)return b;var c=this._clip.duration,d=this.loop,e=this._loopCount;if(2200===
-d)a:{if(-1===e&&(this._loopCount=0,this._setEndings(!0,!0,!1)),b>=c)b=c;else if(0>b)b=0;else break a;this.clampWhenFinished?this.paused=!0:this.enabled=!1;this._mixer.dispatchEvent({type:"finished",action:this,direction:0>a?-1:1})}else{d=2202===d;-1===e&&(0<=a?(e=0,this._setEndings(!0,0===this.repetitions,d)):this._setEndings(0===this.repetitions,!0,d));if(b>=c||0>b){var f=Math.floor(b/c),b=b-c*f,e=e+Math.abs(f),g=this.repetitions-e;0>g?(this.clampWhenFinished?this.paused=!0:this.enabled=!1,b=0<a?
-c:0,this._mixer.dispatchEvent({type:"finished",action:this,direction:0<a?1:-1})):(0===g?(a=0>a,this._setEndings(a,!a,d)):this._setEndings(!1,!1,d),this._loopCount=e,this._mixer.dispatchEvent({type:"loop",action:this,loopDelta:f}))}if(d&&1===(e&1))return this.time=b,c-b}return this.time=b},_setEndings:function(a,b,c){var d=this._interpolantSettings;c?(d.endingStart=2401,d.endingEnd=2401):(d.endingStart=a?this.zeroSlopeAtStart?2401:2400:2402,d.endingEnd=b?this.zeroSlopeAtEnd?2401:2400:2402)},_scheduleFading:function(a,
-b,c){var d=this._mixer,e=d.time,f=this._weightInterpolant;null===f&&(this._weightInterpolant=f=d._lendControlInterpolant());d=f.parameterPositions;f=f.sampleValues;d[0]=e;f[0]=b;d[1]=e+a;f[1]=c;return this}});Object.assign(We.prototype,xa.prototype,{_bindAction:function(a,b){var c=a._localRoot||this._root,d=a._clip.tracks,e=d.length,f=a._propertyBindings,g=a._interpolants,h=c.uuid,k=this._bindingsByRootAndName,l=k[h];void 0===l&&(l={},k[h]=l);for(k=0;k!==e;++k){var n=d[k],v=n.name,p=l[v];if(void 0===
-p){p=f[k];if(void 0!==p){null===p._cacheIndex&&(++p.referenceCount,this._addInactiveBinding(p,h,v));continue}p=new ke(ha.create(c,v,b&&b._propertyBindings[k].binding.parsedPath),n.ValueTypeName,n.getValueSize());++p.referenceCount;this._addInactiveBinding(p,h,v)}f[k]=p;g[k].resultBuffer=p.buffer}},_activateAction:function(a){if(!this._isActiveAction(a)){if(null===a._cacheIndex){var b=(a._localRoot||this._root).uuid,c=a._clip.uuid,d=this._actionsByClip[c];this._bindAction(a,d&&d.knownActions[0]);this._addInactiveAction(a,
-c,b)}b=a._propertyBindings;c=0;for(d=b.length;c!==d;++c){var e=b[c];0===e.useCount++&&(this._lendBinding(e),e.saveOriginalState())}this._lendAction(a)}},_deactivateAction:function(a){if(this._isActiveAction(a)){for(var b=a._propertyBindings,c=0,d=b.length;c!==d;++c){var e=b[c];0===--e.useCount&&(e.restoreOriginalState(),this._takeBackBinding(e))}this._takeBackAction(a)}},_initMemoryManager:function(){this._actions=[];this._nActiveActions=0;this._actionsByClip={};this._bindings=[];this._nActiveBindings=
-0;this._bindingsByRootAndName={};this._controlInterpolants=[];this._nActiveControlInterpolants=0;var a=this;this.stats={actions:{get total(){return a._actions.length},get inUse(){return a._nActiveActions}},bindings:{get total(){return a._bindings.length},get inUse(){return a._nActiveBindings}},controlInterpolants:{get total(){return a._controlInterpolants.length},get inUse(){return a._nActiveControlInterpolants}}}},_isActiveAction:function(a){a=a._cacheIndex;return null!==a&&a<this._nActiveActions},
-_addInactiveAction:function(a,b,c){var d=this._actions,e=this._actionsByClip,f=e[b];void 0===f?(f={knownActions:[a],actionByRoot:{}},a._byClipCacheIndex=0,e[b]=f):(b=f.knownActions,a._byClipCacheIndex=b.length,b.push(a));a._cacheIndex=d.length;d.push(a);f.actionByRoot[c]=a},_removeInactiveAction:function(a){var b=this._actions,c=b[b.length-1],d=a._cacheIndex;c._cacheIndex=d;b[d]=c;b.pop();a._cacheIndex=null;var b=a._clip.uuid,c=this._actionsByClip,d=c[b],e=d.knownActions,f=e[e.length-1],g=a._byClipCacheIndex;
-f._byClipCacheIndex=g;e[g]=f;e.pop();a._byClipCacheIndex=null;delete d.actionByRoot[(a._localRoot||this._root).uuid];0===e.length&&delete c[b];this._removeInactiveBindingsForAction(a)},_removeInactiveBindingsForAction:function(a){a=a._propertyBindings;for(var b=0,c=a.length;b!==c;++b){var d=a[b];0===--d.referenceCount&&this._removeInactiveBinding(d)}},_lendAction:function(a){var b=this._actions,c=a._cacheIndex,d=this._nActiveActions++,e=b[d];a._cacheIndex=d;b[d]=a;e._cacheIndex=c;b[c]=e},_takeBackAction:function(a){var b=
-this._actions,c=a._cacheIndex,d=--this._nActiveActions,e=b[d];a._cacheIndex=d;b[d]=a;e._cacheIndex=c;b[c]=e},_addInactiveBinding:function(a,b,c){var d=this._bindingsByRootAndName,e=d[b],f=this._bindings;void 0===e&&(e={},d[b]=e);e[c]=a;a._cacheIndex=f.length;f.push(a)},_removeInactiveBinding:function(a){var b=this._bindings,c=a.binding,d=c.rootNode.uuid,c=c.path,e=this._bindingsByRootAndName,f=e[d],g=b[b.length-1];a=a._cacheIndex;g._cacheIndex=a;b[a]=g;b.pop();delete f[c];a:{for(var h in f)break a;
-delete e[d]}},_lendBinding:function(a){var b=this._bindings,c=a._cacheIndex,d=this._nActiveBindings++,e=b[d];a._cacheIndex=d;b[d]=a;e._cacheIndex=c;b[c]=e},_takeBackBinding:function(a){var b=this._bindings,c=a._cacheIndex,d=--this._nActiveBindings,e=b[d];a._cacheIndex=d;b[d]=a;e._cacheIndex=c;b[c]=e},_lendControlInterpolant:function(){var a=this._controlInterpolants,b=this._nActiveControlInterpolants++,c=a[b];void 0===c&&(c=new Tc(new Float32Array(2),new Float32Array(2),1,this._controlInterpolantsResultBuffer),
-c.__cacheIndex=b,a[b]=c);return c},_takeBackControlInterpolant:function(a){var b=this._controlInterpolants,c=a.__cacheIndex,d=--this._nActiveControlInterpolants,e=b[d];a.__cacheIndex=d;b[d]=a;e.__cacheIndex=c;b[c]=e},_controlInterpolantsResultBuffer:new Float32Array(1),clipAction:function(a,b){var c=b||this._root,d=c.uuid,e="string"===typeof a?Da.findByName(c,a):a,c=null!==e?e.uuid:a,f=this._actionsByClip[c],g=null;if(void 0!==f){g=f.actionByRoot[d];if(void 0!==g)return g;g=f.knownActions[0];null===
-e&&(e=g._clip)}if(null===e)return null;e=new Ve(this,e,b);this._bindAction(e,g);this._addInactiveAction(e,c,d);return e},existingAction:function(a,b){var c=b||this._root,d=c.uuid,c="string"===typeof a?Da.findByName(c,a):a,c=this._actionsByClip[c?c.uuid:a];return void 0!==c?c.actionByRoot[d]||null:null},stopAllAction:function(){for(var a=this._actions,b=this._nActiveActions,c=this._bindings,d=this._nActiveBindings,e=this._nActiveBindings=this._nActiveActions=0;e!==b;++e)a[e].reset();for(e=0;e!==d;++e)c[e].useCount=
-0;return this},update:function(a){a*=this.timeScale;for(var b=this._actions,c=this._nActiveActions,d=this.time+=a,e=Math.sign(a),f=this._accuIndex^=1,g=0;g!==c;++g)b[g]._update(d,a,e,f);a=this._bindings;b=this._nActiveBindings;for(g=0;g!==b;++g)a[g].apply(f);return this},getRoot:function(){return this._root},uncacheClip:function(a){var b=this._actions;a=a.uuid;var c=this._actionsByClip,d=c[a];if(void 0!==d){for(var d=d.knownActions,e=0,f=d.length;e!==f;++e){var g=d[e];this._deactivateAction(g);var h=
-g._cacheIndex,k=b[b.length-1];g._cacheIndex=null;g._byClipCacheIndex=null;k._cacheIndex=h;b[h]=k;b.pop();this._removeInactiveBindingsForAction(g)}delete c[a]}},uncacheRoot:function(a){a=a.uuid;var b=this._actionsByClip,c;for(c in b){var d=b[c].actionByRoot[a];void 0!==d&&(this._deactivateAction(d),this._removeInactiveAction(d))}c=this._bindingsByRootAndName[a];if(void 0!==c)for(var e in c)a=c[e],a.restoreOriginalState(),this._removeInactiveBinding(a)},uncacheAction:function(a,b){var c=this.existingAction(a,
-b);null!==c&&(this._deactivateAction(c),this._removeInactiveAction(c))}});Id.prototype.clone=function(){return new Id(void 0===this.value.clone?this.value:this.value.clone())};le.prototype=Object.assign(Object.create(E.prototype),{constructor:le,isInstancedBufferGeometry:!0,addGroup:function(a,b,c){this.groups.push({start:a,count:b,materialIndex:c})},copy:function(a){var b=a.index;null!==b&&this.setIndex(b.clone());var b=a.attributes,c;for(c in b)this.addAttribute(c,b[c].clone());a=a.groups;c=0;for(b=
-a.length;c<b;c++){var d=a[c];this.addGroup(d.start,d.count,d.materialIndex)}return this}});Object.defineProperties(me.prototype,{count:{get:function(){return this.data.count}},array:{get:function(){return this.data.array}}});Object.assign(me.prototype,{isInterleavedBufferAttribute:!0,setX:function(a,b){this.data.array[a*this.data.stride+this.offset]=b;return this},setY:function(a,b){this.data.array[a*this.data.stride+this.offset+1]=b;return this},setZ:function(a,b){this.data.array[a*this.data.stride+
-this.offset+2]=b;return this},setW:function(a,b){this.data.array[a*this.data.stride+this.offset+3]=b;return this},getX:function(a){return this.data.array[a*this.data.stride+this.offset]},getY:function(a){return this.data.array[a*this.data.stride+this.offset+1]},getZ:function(a){return this.data.array[a*this.data.stride+this.offset+2]},getW:function(a){return this.data.array[a*this.data.stride+this.offset+3]},setXY:function(a,b,c){a=a*this.data.stride+this.offset;this.data.array[a+0]=b;this.data.array[a+
-1]=c;return this},setXYZ:function(a,b,c,d){a=a*this.data.stride+this.offset;this.data.array[a+0]=b;this.data.array[a+1]=c;this.data.array[a+2]=d;return this},setXYZW:function(a,b,c,d,e){a=a*this.data.stride+this.offset;this.data.array[a+0]=b;this.data.array[a+1]=c;this.data.array[a+2]=d;this.data.array[a+3]=e;return this}});Object.defineProperty(ic.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.assign(ic.prototype,{isInterleavedBuffer:!0,setArray:function(a){if(Array.isArray(a))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");
-this.count=void 0!==a?a.length/this.stride:0;this.array=a},setDynamic:function(a){this.dynamic=a;return this},copy:function(a){this.array=new a.array.constructor(a.array);this.count=a.count;this.stride=a.stride;this.dynamic=a.dynamic;return this},copyAt:function(a,b,c){a*=this.stride;c*=b.stride;for(var d=0,e=this.stride;d<e;d++)this.array[a+d]=b.array[c+d];return this},set:function(a,b){void 0===b&&(b=0);this.array.set(a,b);return this},clone:function(){return(new this.constructor).copy(this)},onUpload:function(a){this.onUploadCallback=
-a;return this}});ne.prototype=Object.assign(Object.create(ic.prototype),{constructor:ne,isInstancedInterleavedBuffer:!0,copy:function(a){ic.prototype.copy.call(this,a);this.meshPerAttribute=a.meshPerAttribute;return this}});oe.prototype=Object.assign(Object.create(Z.prototype),{constructor:oe,isInstancedBufferAttribute:!0,copy:function(a){Z.prototype.copy.call(this,a);this.meshPerAttribute=a.meshPerAttribute;return this}});Object.assign(Xe.prototype,{linePrecision:1,set:function(a,b){this.ray.set(a,
-b)},setFromCamera:function(a,b){b&&b.isPerspectiveCamera?(this.ray.origin.setFromMatrixPosition(b.matrixWorld),this.ray.direction.set(a.x,a.y,.5).unproject(b).sub(this.ray.origin).normalize()):b&&b.isOrthographicCamera?(this.ray.origin.set(a.x,a.y,(b.near+b.far)/(b.near-b.far)).unproject(b),this.ray.direction.set(0,0,-1).transformDirection(b.matrixWorld)):console.error("THREE.Raycaster: Unsupported camera type.")},intersectObject:function(a,b){var c=[];pe(a,this,c,b);c.sort(Ye);return c},intersectObjects:function(a,
-b){var c=[];if(!1===Array.isArray(a))return console.warn("THREE.Raycaster.intersectObjects: objects is not an Array."),c;for(var d=0,e=a.length;d<e;d++)pe(a[d],this,c,b);c.sort(Ye);return c}});Object.assign(Ze.prototype,{start:function(){this.oldTime=this.startTime=("undefined"===typeof performance?Date:performance).now();this.elapsedTime=0;this.running=!0},stop:function(){this.getElapsedTime();this.autoStart=this.running=!1},getElapsedTime:function(){this.getDelta();return this.elapsedTime},getDelta:function(){var a=
-0;if(this.autoStart&&!this.running)return this.start(),0;if(this.running){var b=("undefined"===typeof performance?Date:performance).now(),a=(b-this.oldTime)/1E3;this.oldTime=b;this.elapsedTime+=a}return a}});Object.assign($e.prototype,{set:function(a,b,c){this.radius=a;this.phi=b;this.theta=c;return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.radius=a.radius;this.phi=a.phi;this.theta=a.theta;return this},makeSafe:function(){this.phi=Math.max(1E-6,Math.min(Math.PI-
-1E-6,this.phi));return this},setFromVector3:function(a){this.radius=a.length();0===this.radius?this.phi=this.theta=0:(this.theta=Math.atan2(a.x,a.z),this.phi=Math.acos(Y.clamp(a.y/this.radius,-1,1)));return this}});Object.assign(af.prototype,{set:function(a,b,c){this.radius=a;this.theta=b;this.y=c;return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.radius=a.radius;this.theta=a.theta;this.y=a.y;return this},setFromVector3:function(a){this.radius=Math.sqrt(a.x*
-a.x+a.z*a.z);this.theta=Math.atan2(a.x,a.z);this.y=a.y;return this}});ta.prototype=Object.create(la.prototype);ta.prototype.constructor=ta;ta.prototype.createAnimation=function(a,b,c,d){b={start:b,end:c,length:c-b+1,fps:d,duration:(c-b)/d,lastFrame:0,currentFrame:0,active:!1,time:0,direction:1,weight:1,directionBackwards:!1,mirroredLoop:!1};this.animationsMap[a]=b;this.animationsList.push(b)};ta.prototype.autoCreateAnimations=function(a){for(var b=/([a-z]+)_?(\d+)/i,c,d={},e=this.geometry,f=0,g=e.morphTargets.length;f<
-g;f++){var h=e.morphTargets[f].name.match(b);if(h&&1<h.length){var k=h[1];d[k]||(d[k]={start:Infinity,end:-Infinity});h=d[k];f<h.start&&(h.start=f);f>h.end&&(h.end=f);c||(c=k)}}for(k in d)h=d[k],this.createAnimation(k,h.start,h.end,a);this.firstAnimation=c};ta.prototype.setAnimationDirectionForward=function(a){if(a=this.animationsMap[a])a.direction=1,a.directionBackwards=!1};ta.prototype.setAnimationDirectionBackward=function(a){if(a=this.animationsMap[a])a.direction=-1,a.directionBackwards=!0};ta.prototype.setAnimationFPS=
-function(a,b){var c=this.animationsMap[a];c&&(c.fps=b,c.duration=(c.end-c.start)/c.fps)};ta.prototype.setAnimationDuration=function(a,b){var c=this.animationsMap[a];c&&(c.duration=b,c.fps=(c.end-c.start)/c.duration)};ta.prototype.setAnimationWeight=function(a,b){var c=this.animationsMap[a];c&&(c.weight=b)};ta.prototype.setAnimationTime=function(a,b){var c=this.animationsMap[a];c&&(c.time=b)};ta.prototype.getAnimationTime=function(a){var b=0;if(a=this.animationsMap[a])b=a.time;return b};ta.prototype.getAnimationDuration=
-function(a){var b=-1;if(a=this.animationsMap[a])b=a.duration;return b};ta.prototype.playAnimation=function(a){var b=this.animationsMap[a];b?(b.time=0,b.active=!0):console.warn("THREE.MorphBlendMesh: animation["+a+"] undefined in .playAnimation()")};ta.prototype.stopAnimation=function(a){if(a=this.animationsMap[a])a.active=!1};ta.prototype.update=function(a){for(var b=0,c=this.animationsList.length;b<c;b++){var d=this.animationsList[b];if(d.active){var e=d.duration/d.length;d.time+=d.direction*a;if(d.mirroredLoop){if(d.time>
-d.duration||0>d.time)d.direction*=-1,d.time>d.duration&&(d.time=d.duration,d.directionBackwards=!0),0>d.time&&(d.time=0,d.directionBackwards=!1)}else d.time%=d.duration,0>d.time&&(d.time+=d.duration);var f=d.start+Y.clamp(Math.floor(d.time/e),0,d.length-1),g=d.weight;f!==d.currentFrame&&(this.morphTargetInfluences[d.lastFrame]=0,this.morphTargetInfluences[d.currentFrame]=1*g,this.morphTargetInfluences[f]=0,d.lastFrame=d.currentFrame,d.currentFrame=f);e=d.time%e/e;d.directionBackwards&&(e=1-e);d.currentFrame!==
-d.lastFrame?(this.morphTargetInfluences[d.currentFrame]=e*g,this.morphTargetInfluences[d.lastFrame]=(1-e)*g):this.morphTargetInfluences[d.currentFrame]=g}}};Xc.prototype=Object.create(z.prototype);Xc.prototype.constructor=Xc;Xc.prototype.isImmediateRenderObject=!0;Yc.prototype=Object.create(Q.prototype);Yc.prototype.constructor=Yc;Yc.prototype.update=function(){var a=new n,b=new n,c=new Ba;return function(){var d=["a","b","c"];this.object.updateMatrixWorld(!0);c.getNormalMatrix(this.object.matrixWorld);
-var e=this.object.matrixWorld,f=this.geometry.attributes.position,g=this.object.geometry;if(g&&g.isGeometry)for(var h=g.vertices,k=g.faces,l=g=0,n=k.length;l<n;l++)for(var v=k[l],p=0,r=v.vertexNormals.length;p<r;p++){var z=v.vertexNormals[p];a.copy(h[v[d[p]]]).applyMatrix4(e);b.copy(z).applyMatrix3(c).normalize().multiplyScalar(this.size).add(a);f.setXYZ(g,a.x,a.y,a.z);g+=1;f.setXYZ(g,b.x,b.y,b.z);g+=1}else if(g&&g.isBufferGeometry)for(d=g.attributes.position,h=g.attributes.normal,p=g=0,r=d.count;p<
-r;p++)a.set(d.getX(p),d.getY(p),d.getZ(p)).applyMatrix4(e),b.set(h.getX(p),h.getY(p),h.getZ(p)),b.applyMatrix3(c).normalize().multiplyScalar(this.size).add(a),f.setXYZ(g,a.x,a.y,a.z),g+=1,f.setXYZ(g,b.x,b.y,b.z),g+=1;f.needsUpdate=!0}}();jc.prototype=Object.create(z.prototype);jc.prototype.constructor=jc;jc.prototype.dispose=function(){this.cone.geometry.dispose();this.cone.material.dispose()};jc.prototype.update=function(){var a=new n,b=new n;return function(){this.light.updateMatrixWorld();var c=
-this.light.distance?this.light.distance:1E3,d=c*Math.tan(this.light.angle);this.cone.scale.set(d,d,c);a.setFromMatrixPosition(this.light.matrixWorld);b.setFromMatrixPosition(this.light.target.matrixWorld);this.cone.lookAt(b.sub(a));this.cone.material.color.copy(this.light.color)}}();kc.prototype=Object.create(Q.prototype);kc.prototype.constructor=kc;kc.prototype.onBeforeRender=function(){var a=new n,b=new K,c=new K;return function(){var d=this.bones,e=this.geometry,f=e.getAttribute("position");c.getInverse(this.root.matrixWorld);
-for(var g=0,h=0;g<d.length;g++){var k=d[g];k.parent&&k.parent.isBone&&(b.multiplyMatrices(c,k.matrixWorld),a.setFromMatrixPosition(b),f.setXYZ(h,a.x,a.y,a.z),b.multiplyMatrices(c,k.parent.matrixWorld),a.setFromMatrixPosition(b),f.setXYZ(h+1,a.x,a.y,a.z),h+=2)}e.getAttribute("position").needsUpdate=!0}}();lc.prototype=Object.create(la.prototype);lc.prototype.constructor=lc;lc.prototype.dispose=function(){this.geometry.dispose();this.material.dispose()};lc.prototype.update=function(){this.material.color.copy(this.light.color)};
-mc.prototype=Object.create(z.prototype);mc.prototype.constructor=mc;mc.prototype.dispose=function(){this.children[0].geometry.dispose();this.children[0].material.dispose()};mc.prototype.update=function(){var a=this.children[0];a.material.color.copy(this.light.color);var b=.5*this.light.width,c=.5*this.light.height,a=a.geometry.attributes.position,d=a.array;d[0]=b;d[1]=-c;d[2]=0;d[3]=b;d[4]=c;d[5]=0;d[6]=-b;d[7]=c;d[8]=0;d[9]=-b;d[10]=-c;d[11]=0;d[12]=b;d[13]=-c;d[14]=0;a.needsUpdate=!0};nc.prototype=
-Object.create(z.prototype);nc.prototype.constructor=nc;nc.prototype.dispose=function(){this.children[0].geometry.dispose();this.children[0].material.dispose()};nc.prototype.update=function(){var a=new n,b=new G,c=new G;return function(){var d=this.children[0],e=d.geometry.getAttribute("color");b.copy(this.light.color);c.copy(this.light.groundColor);for(var f=0,g=e.count;f<g;f++){var h=f<g/2?b:c;e.setXYZ(f,h.r,h.g,h.b)}d.lookAt(a.setFromMatrixPosition(this.light.matrixWorld).negate());e.needsUpdate=
-!0}}();Zc.prototype=Object.create(Q.prototype);Zc.prototype.constructor=Zc;Jd.prototype=Object.create(Q.prototype);Jd.prototype.constructor=Jd;$c.prototype=Object.create(Q.prototype);$c.prototype.constructor=$c;$c.prototype.update=function(){var a=new n,b=new n,c=new Ba;return function(){this.object.updateMatrixWorld(!0);c.getNormalMatrix(this.object.matrixWorld);for(var d=this.object.matrixWorld,e=this.geometry.attributes.position,f=this.object.geometry,g=f.vertices,f=f.faces,h=0,k=0,l=f.length;k<
-l;k++){var n=f[k],v=n.normal;a.copy(g[n.a]).add(g[n.b]).add(g[n.c]).divideScalar(3).applyMatrix4(d);b.copy(v).applyMatrix3(c).normalize().multiplyScalar(this.size).add(a);e.setXYZ(h,a.x,a.y,a.z);h+=1;e.setXYZ(h,b.x,b.y,b.z);h+=1}e.needsUpdate=!0}}();oc.prototype=Object.create(z.prototype);oc.prototype.constructor=oc;oc.prototype.dispose=function(){var a=this.children[0],b=this.children[1];a.geometry.dispose();a.material.dispose();b.geometry.dispose();b.material.dispose()};oc.prototype.update=function(){var a=
-new n,b=new n,c=new n;return function(){a.setFromMatrixPosition(this.light.matrixWorld);b.setFromMatrixPosition(this.light.target.matrixWorld);c.subVectors(b,a);var d=this.children[0],e=this.children[1];d.lookAt(c);d.material.color.copy(this.light.color);e.lookAt(c);e.scale.z=c.length()}}();ad.prototype=Object.create(Q.prototype);ad.prototype.constructor=ad;ad.prototype.update=function(){function a(a,g,h,k){d.set(g,h,k).unproject(e);a=c[a];if(void 0!==a)for(g=b.getAttribute("position"),h=0,k=a.length;h<
-k;h++)g.setXYZ(a[h],d.x,d.y,d.z)}var b,c,d=new n,e=new Na;return function(){b=this.geometry;c=this.pointMap;e.projectionMatrix.copy(this.camera.projectionMatrix);a("c",0,0,-1);a("t",0,0,1);a("n1",-1,-1,-1);a("n2",1,-1,-1);a("n3",-1,1,-1);a("n4",1,1,-1);a("f1",-1,-1,1);a("f2",1,-1,1);a("f3",-1,1,1);a("f4",1,1,1);a("u1",.7,1.1,-1);a("u2",-.7,1.1,-1);a("u3",0,2,-1);a("cf1",-1,0,1);a("cf2",1,0,1);a("cf3",0,-1,1);a("cf4",0,1,1);a("cn1",-1,0,-1);a("cn2",1,0,-1);a("cn3",0,-1,-1);a("cn4",0,1,-1);b.getAttribute("position").needsUpdate=
-!0}}();Ab.prototype=Object.create(Q.prototype);Ab.prototype.constructor=Ab;Ab.prototype.update=function(){var a=new Ra;return function(b){void 0!==b&&console.warn("THREE.BoxHelper: .update() has no longer arguments.");void 0!==this.object&&a.setFromObject(this.object);if(!a.isEmpty()){b=a.min;var c=a.max,d=this.geometry.attributes.position,e=d.array;e[0]=c.x;e[1]=c.y;e[2]=c.z;e[3]=b.x;e[4]=c.y;e[5]=c.z;e[6]=b.x;e[7]=b.y;e[8]=c.z;e[9]=c.x;e[10]=b.y;e[11]=c.z;e[12]=c.x;e[13]=c.y;e[14]=b.z;e[15]=b.x;
-e[16]=c.y;e[17]=b.z;e[18]=b.x;e[19]=b.y;e[20]=b.z;e[21]=c.x;e[22]=b.y;e[23]=b.z;d.needsUpdate=!0;this.geometry.computeBoundingSphere()}}}();Ab.prototype.setFromObject=function(a){this.object=a;this.update();return this};var Kd,qe;Bb.prototype=Object.create(z.prototype);Bb.prototype.constructor=Bb;Bb.prototype.setDirection=function(){var a=new n,b;return function(c){.99999<c.y?this.quaternion.set(0,0,0,1):-.99999>c.y?this.quaternion.set(1,0,0,0):(a.set(c.z,0,-c.x).normalize(),b=Math.acos(c.y),this.quaternion.setFromAxisAngle(a,
-b))}}();Bb.prototype.setLength=function(a,b,c){void 0===b&&(b=.2*a);void 0===c&&(c=.2*b);this.line.scale.set(1,Math.max(0,a-b),1);this.line.updateMatrix();this.cone.scale.set(c,b,c);this.cone.position.y=a;this.cone.updateMatrix()};Bb.prototype.setColor=function(a){this.line.material.color.copy(a);this.cone.material.color.copy(a)};Ld.prototype=Object.create(Q.prototype);Ld.prototype.constructor=Ld;var Od=new n,ue=new re,ve=new re,we=new re;La.prototype=Object.create(ua.prototype);La.prototype.constructor=
-La;La.prototype.getPoint=function(a){var b=this.points,c=b.length;a*=c-(this.closed?0:1);var d=Math.floor(a);a-=d;this.closed?d+=0<d?0:(Math.floor(Math.abs(d)/b.length)+1)*b.length:0===a&&d===c-1&&(d=c-2,a=1);var e,f,g;this.closed||0<d?e=b[(d-1)%c]:(Od.subVectors(b[0],b[1]).add(b[0]),e=Od);f=b[d%c];g=b[(d+1)%c];this.closed||d+2<c?b=b[(d+2)%c]:(Od.subVectors(b[c-1],b[c-2]).add(b[c-1]),b=Od);if(void 0===this.type||"centripetal"===this.type||"chordal"===this.type){var h="chordal"===this.type?.5:.25,
-c=Math.pow(e.distanceToSquared(f),h),d=Math.pow(f.distanceToSquared(g),h),h=Math.pow(g.distanceToSquared(b),h);1E-4>d&&(d=1);1E-4>c&&(c=d);1E-4>h&&(h=d);ue.initNonuniformCatmullRom(e.x,f.x,g.x,b.x,c,d,h);ve.initNonuniformCatmullRom(e.y,f.y,g.y,b.y,c,d,h);we.initNonuniformCatmullRom(e.z,f.z,g.z,b.z,c,d,h)}else"catmullrom"===this.type&&(c=void 0!==this.tension?this.tension:.5,ue.initCatmullRom(e.x,f.x,g.x,b.x,c),ve.initCatmullRom(e.y,f.y,g.y,b.y,c),we.initCatmullRom(e.z,f.z,g.z,b.z,c));return new n(ue.calc(a),
-ve.calc(a),we.calc(a))};bd.prototype=Object.create(ua.prototype);bd.prototype.constructor=bd;bd.prototype.getPoint=function(a){var b=this.v0,c=this.v1,d=this.v2,e=this.v3;return new n(xb(a,b.x,c.x,d.x,e.x),xb(a,b.y,c.y,d.y,e.y),xb(a,b.z,c.z,d.z,e.z))};cd.prototype=Object.create(ua.prototype);cd.prototype.constructor=cd;cd.prototype.getPoint=function(a){var b=this.v0,c=this.v1,d=this.v2;return new n(wb(a,b.x,c.x,d.x),wb(a,b.y,c.y,d.y),wb(a,b.z,c.z,d.z))};dd.prototype=Object.create(ua.prototype);dd.prototype.constructor=
-dd;dd.prototype.getPoint=function(a){if(1===a)return this.v2.clone();var b=new n;b.subVectors(this.v2,this.v1);b.multiplyScalar(a);b.add(this.v1);return b};Md.prototype=Object.create(Va.prototype);Md.prototype.constructor=Md;ua.create=function(a,b){console.log("THREE.Curve.create() has been deprecated");a.prototype=Object.create(ua.prototype);a.prototype.constructor=a;a.prototype.getPoint=b;return a};cf.prototype=Object.create(La.prototype);df.prototype=Object.create(La.prototype);se.prototype=Object.create(La.prototype);
-Object.assign(se.prototype,{initFromArray:function(a){console.error("THREE.Spline: .initFromArray() has been removed.")},getControlPointsArray:function(a){console.error("THREE.Spline: .getControlPointsArray() has been removed.")},reparametrizeByArcLength:function(a){console.error("THREE.Spline: .reparametrizeByArcLength() has been removed.")}});Zc.prototype.setColors=function(){console.error("THREE.GridHelper: setColors() has been deprecated, pass them in the constructor instead.")};kc.prototype.update=
-function(){console.error("THREE.SkeletonHelper: update() no longer needs to be called.")};Object.assign(fd.prototype,{center:function(a){console.warn("THREE.Box2: .center() has been renamed to .getCenter().");return this.getCenter(a)},empty:function(){console.warn("THREE.Box2: .empty() has been renamed to .isEmpty().");return this.isEmpty()},isIntersectionBox:function(a){console.warn("THREE.Box2: .isIntersectionBox() has been renamed to .intersectsBox().");return this.intersectsBox(a)},size:function(a){console.warn("THREE.Box2: .size() has been renamed to .getSize().");
-return this.getSize(a)}});Object.assign(Ra.prototype,{center:function(a){console.warn("THREE.Box3: .center() has been renamed to .getCenter().");return this.getCenter(a)},empty:function(){console.warn("THREE.Box3: .empty() has been renamed to .isEmpty().");return this.isEmpty()},isIntersectionBox:function(a){console.warn("THREE.Box3: .isIntersectionBox() has been renamed to .intersectsBox().");return this.intersectsBox(a)},isIntersectionSphere:function(a){console.warn("THREE.Box3: .isIntersectionSphere() has been renamed to .intersectsSphere().");
-return this.intersectsSphere(a)},size:function(a){console.warn("THREE.Box3: .size() has been renamed to .getSize().");return this.getSize(a)}});Hb.prototype.center=function(a){console.warn("THREE.Line3: .center() has been renamed to .getCenter().");return this.getCenter(a)};Y.random16=function(){console.warn("THREE.Math.random16() has been deprecated. Use Math.random() instead.");return Math.random()};Object.assign(Ba.prototype,{flattenToArrayOffset:function(a,b){console.warn("THREE.Matrix3: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.");
-return this.toArray(a,b)},multiplyVector3:function(a){console.warn("THREE.Matrix3: .multiplyVector3() has been removed. Use vector.applyMatrix3( matrix ) instead.");return a.applyMatrix3(this)},multiplyVector3Array:function(a){console.error("THREE.Matrix3: .multiplyVector3Array() has been removed.")},applyToBuffer:function(a,b,c){console.warn("THREE.Matrix3: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.");return this.applyToBufferAttribute(a)},applyToVector3Array:function(a,
-b,c){console.error("THREE.Matrix3: .applyToVector3Array() has been removed.")}});Object.assign(K.prototype,{extractPosition:function(a){console.warn("THREE.Matrix4: .extractPosition() has been renamed to .copyPosition().");return this.copyPosition(a)},flattenToArrayOffset:function(a,b){console.warn("THREE.Matrix4: .flattenToArrayOffset() has been deprecated. Use .toArray() instead.");return this.toArray(a,b)},getPosition:function(){var a;return function(){void 0===a&&(a=new n);console.warn("THREE.Matrix4: .getPosition() has been removed. Use Vector3.setFromMatrixPosition( matrix ) instead.");
-return a.setFromMatrixColumn(this,3)}}(),setRotationFromQuaternion:function(a){console.warn("THREE.Matrix4: .setRotationFromQuaternion() has been renamed to .makeRotationFromQuaternion().");return this.makeRotationFromQuaternion(a)},multiplyToArray:function(){console.warn("THREE.Matrix4: .multiplyToArray() has been removed.")},multiplyVector3:function(a){console.warn("THREE.Matrix4: .multiplyVector3() has been removed. Use vector.applyMatrix4( matrix ) instead.");return a.applyMatrix4(this)},multiplyVector4:function(a){console.warn("THREE.Matrix4: .multiplyVector4() has been removed. Use vector.applyMatrix4( matrix ) instead.");
-return a.applyMatrix4(this)},multiplyVector3Array:function(a){console.error("THREE.Matrix4: .multiplyVector3Array() has been removed.")},rotateAxis:function(a){console.warn("THREE.Matrix4: .rotateAxis() has been removed. Use Vector3.transformDirection( matrix ) instead.");a.transformDirection(this)},crossVector:function(a){console.warn("THREE.Matrix4: .crossVector() has been removed. Use vector.applyMatrix4( matrix ) instead.");return a.applyMatrix4(this)},translate:function(){console.error("THREE.Matrix4: .translate() has been removed.")},
-rotateX:function(){console.error("THREE.Matrix4: .rotateX() has been removed.")},rotateY:function(){console.error("THREE.Matrix4: .rotateY() has been removed.")},rotateZ:function(){console.error("THREE.Matrix4: .rotateZ() has been removed.")},rotateByAxis:function(){console.error("THREE.Matrix4: .rotateByAxis() has been removed.")},applyToBuffer:function(a,b,c){console.warn("THREE.Matrix4: .applyToBuffer() has been removed. Use matrix.applyToBufferAttribute( attribute ) instead.");return this.applyToBufferAttribute(a)},
-applyToVector3Array:function(a,b,c){console.error("THREE.Matrix4: .applyToVector3Array() has been removed.")},makeFrustum:function(a,b,c,d,e,f){console.warn("THREE.Matrix4: .makeFrustum() has been removed. Use .makePerspective( left, right, top, bottom, near, far ) instead.");return this.makePerspective(a,b,d,c,e,f)}});Aa.prototype.isIntersectionLine=function(a){console.warn("THREE.Plane: .isIntersectionLine() has been renamed to .intersectsLine().");return this.intersectsLine(a)};oa.prototype.multiplyVector3=
-function(a){console.warn("THREE.Quaternion: .multiplyVector3() has been removed. Use is now vector.applyQuaternion( quaternion ) instead.");return a.applyQuaternion(this)};Object.assign(kb.prototype,{isIntersectionBox:function(a){console.warn("THREE.Ray: .isIntersectionBox() has been renamed to .intersectsBox().");return this.intersectsBox(a)},isIntersectionPlane:function(a){console.warn("THREE.Ray: .isIntersectionPlane() has been renamed to .intersectsPlane().");return this.intersectsPlane(a)},isIntersectionSphere:function(a){console.warn("THREE.Ray: .isIntersectionSphere() has been renamed to .intersectsSphere().");
-return this.intersectsSphere(a)}});Object.assign(zb.prototype,{extrude:function(a){console.warn("THREE.Shape: .extrude() has been removed. Use ExtrudeGeometry() instead.");return new cb(this,a)},makeGeometry:function(a){console.warn("THREE.Shape: .makeGeometry() has been removed. Use ShapeGeometry() instead.");return new Xb(this,a)}});Object.assign(C.prototype,{fromAttribute:function(a,b,c){console.error("THREE.Vector2: .fromAttribute() has been renamed to .fromBufferAttribute().");return this.fromBufferAttribute(a,
-b,c)}});Object.assign(n.prototype,{setEulerFromRotationMatrix:function(){console.error("THREE.Vector3: .setEulerFromRotationMatrix() has been removed. Use Euler.setFromRotationMatrix() instead.")},setEulerFromQuaternion:function(){console.error("THREE.Vector3: .setEulerFromQuaternion() has been removed. Use Euler.setFromQuaternion() instead.")},getPositionFromMatrix:function(a){console.warn("THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().");return this.setFromMatrixPosition(a)},
-getScaleFromMatrix:function(a){console.warn("THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().");return this.setFromMatrixScale(a)},getColumnFromMatrix:function(a,b){console.warn("THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().");return this.setFromMatrixColumn(b,a)},applyProjection:function(a){console.warn("THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.");return this.applyMatrix4(a)},fromAttribute:function(a,
-b,c){console.error("THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().");return this.fromBufferAttribute(a,b,c)}});Object.assign(fa.prototype,{fromAttribute:function(a,b,c){console.error("THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().");return this.fromBufferAttribute(a,b,c)}});J.prototype.computeTangents=function(){console.warn("THREE.Geometry: .computeTangents() has been removed.")};Object.assign(z.prototype,{getChildByName:function(a){console.warn("THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().");
-return this.getObjectByName(a)},renderDepth:function(){console.warn("THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.")},translate:function(a,b){console.warn("THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.");return this.translateOnAxis(b,a)}});Object.defineProperties(z.prototype,{eulerOrder:{get:function(){console.warn("THREE.Object3D: .eulerOrder is now .rotation.order.");return this.rotation.order},set:function(a){console.warn("THREE.Object3D: .eulerOrder is now .rotation.order.");
-this.rotation.order=a}},useQuaternion:{get:function(){console.warn("THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.")},set:function(){console.warn("THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.")}}});Object.defineProperties(yc.prototype,{objects:{get:function(){console.warn("THREE.LOD: .objects has been renamed to .levels.");return this.levels}}});Object.defineProperty(zc.prototype,"useVertexTexture",{get:function(){console.warn("THREE.Skeleton: useVertexTexture has been removed.")},
-set:function(){console.warn("THREE.Skeleton: useVertexTexture has been removed.")}});Object.defineProperty(ua.prototype,"__arcLengthDivisions",{get:function(){console.warn("THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.");return this.arcLengthDivisions},set:function(a){console.warn("THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.");this.arcLengthDivisions=a}});qa.prototype.setLens=function(a,b){console.warn("THREE.PerspectiveCamera.setLens is deprecated. Use .setFocalLength and .filmGauge for a photographic setup.");
-void 0!==b&&(this.filmGauge=b);this.setFocalLength(a)};Object.defineProperties(na.prototype,{onlyShadow:{set:function(){console.warn("THREE.Light: .onlyShadow has been removed.")}},shadowCameraFov:{set:function(a){console.warn("THREE.Light: .shadowCameraFov is now .shadow.camera.fov.");this.shadow.camera.fov=a}},shadowCameraLeft:{set:function(a){console.warn("THREE.Light: .shadowCameraLeft is now .shadow.camera.left.");this.shadow.camera.left=a}},shadowCameraRight:{set:function(a){console.warn("THREE.Light: .shadowCameraRight is now .shadow.camera.right.");
-this.shadow.camera.right=a}},shadowCameraTop:{set:function(a){console.warn("THREE.Light: .shadowCameraTop is now .shadow.camera.top.");this.shadow.camera.top=a}},shadowCameraBottom:{set:function(a){console.warn("THREE.Light: .shadowCameraBottom is now .shadow.camera.bottom.");this.shadow.camera.bottom=a}},shadowCameraNear:{set:function(a){console.warn("THREE.Light: .shadowCameraNear is now .shadow.camera.near.");this.shadow.camera.near=a}},shadowCameraFar:{set:function(a){console.warn("THREE.Light: .shadowCameraFar is now .shadow.camera.far.");
-this.shadow.camera.far=a}},shadowCameraVisible:{set:function(){console.warn("THREE.Light: .shadowCameraVisible has been removed. Use new THREE.CameraHelper( light.shadow.camera ) instead.")}},shadowBias:{set:function(a){console.warn("THREE.Light: .shadowBias is now .shadow.bias.");this.shadow.bias=a}},shadowDarkness:{set:function(){console.warn("THREE.Light: .shadowDarkness has been removed.")}},shadowMapWidth:{set:function(a){console.warn("THREE.Light: .shadowMapWidth is now .shadow.mapSize.width.");
-this.shadow.mapSize.width=a}},shadowMapHeight:{set:function(a){console.warn("THREE.Light: .shadowMapHeight is now .shadow.mapSize.height.");this.shadow.mapSize.height=a}}});Object.defineProperties(Z.prototype,{length:{get:function(){console.warn("THREE.BufferAttribute: .length has been deprecated. Use .count instead.");return this.array.length}}});Object.assign(E.prototype,{addIndex:function(a){console.warn("THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().");this.setIndex(a)},addDrawCall:function(a,
-b,c){void 0!==c&&console.warn("THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.");console.warn("THREE.BufferGeometry: .addDrawCall() is now .addGroup().");this.addGroup(a,b)},clearDrawCalls:function(){console.warn("THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().");this.clearGroups()},computeTangents:function(){console.warn("THREE.BufferGeometry: .computeTangents() has been removed.")},computeOffsets:function(){console.warn("THREE.BufferGeometry: .computeOffsets() has been removed.")}});
-Object.defineProperties(E.prototype,{drawcalls:{get:function(){console.error("THREE.BufferGeometry: .drawcalls has been renamed to .groups.");return this.groups}},offsets:{get:function(){console.warn("THREE.BufferGeometry: .offsets has been renamed to .groups.");return this.groups}}});Object.defineProperties(Id.prototype,{dynamic:{set:function(){console.warn("THREE.Uniform: .dynamic has been removed. Use object.onBeforeRender() instead.")}},onUpdate:{value:function(){console.warn("THREE.Uniform: .onUpdate() has been removed. Use object.onBeforeRender() instead.");
-return this}}});Object.defineProperties(U.prototype,{wrapAround:{get:function(){console.warn("THREE.Material: .wrapAround has been removed.")},set:function(){console.warn("THREE.Material: .wrapAround has been removed.")}},wrapRGB:{get:function(){console.warn("THREE.Material: .wrapRGB has been removed.");return new G}}});Object.defineProperties(Ja.prototype,{metal:{get:function(){console.warn("THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead.");return!1},set:function(){console.warn("THREE.MeshPhongMaterial: .metal has been removed. Use THREE.MeshStandardMaterial instead")}}});
-Object.defineProperties(ra.prototype,{derivatives:{get:function(){console.warn("THREE.ShaderMaterial: .derivatives has been moved to .extensions.derivatives.");return this.extensions.derivatives},set:function(a){console.warn("THREE. ShaderMaterial: .derivatives has been moved to .extensions.derivatives.");this.extensions.derivatives=a}}});Object.assign(Xd.prototype,{getCurrentRenderTarget:function(){console.warn("THREE.WebGLRenderer: .getCurrentRenderTarget() is now .getRenderTarget().");return this.getRenderTarget()},
-supportsFloatTextures:function(){console.warn("THREE.WebGLRenderer: .supportsFloatTextures() is now .extensions.get( 'OES_texture_float' ).");return this.extensions.get("OES_texture_float")},supportsHalfFloatTextures:function(){console.warn("THREE.WebGLRenderer: .supportsHalfFloatTextures() is now .extensions.get( 'OES_texture_half_float' ).");return this.extensions.get("OES_texture_half_float")},supportsStandardDerivatives:function(){console.warn("THREE.WebGLRenderer: .supportsStandardDerivatives() is now .extensions.get( 'OES_standard_derivatives' ).");
-return this.extensions.get("OES_standard_derivatives")},supportsCompressedTextureS3TC:function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTextureS3TC() is now .extensions.get( 'WEBGL_compressed_texture_s3tc' ).");return this.extensions.get("WEBGL_compressed_texture_s3tc")},supportsCompressedTexturePVRTC:function(){console.warn("THREE.WebGLRenderer: .supportsCompressedTexturePVRTC() is now .extensions.get( 'WEBGL_compressed_texture_pvrtc' ).");return this.extensions.get("WEBGL_compressed_texture_pvrtc")},
-supportsBlendMinMax:function(){console.warn("THREE.WebGLRenderer: .supportsBlendMinMax() is now .extensions.get( 'EXT_blend_minmax' ).");return this.extensions.get("EXT_blend_minmax")},supportsVertexTextures:function(){console.warn("THREE.WebGLRenderer: .supportsVertexTextures() is now .capabilities.vertexTextures.");return this.capabilities.vertexTextures},supportsInstancedArrays:function(){console.warn("THREE.WebGLRenderer: .supportsInstancedArrays() is now .extensions.get( 'ANGLE_instanced_arrays' ).");
-return this.extensions.get("ANGLE_instanced_arrays")},enableScissorTest:function(a){console.warn("THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().");this.setScissorTest(a)},initMaterial:function(){console.warn("THREE.WebGLRenderer: .initMaterial() has been removed.")},addPrePlugin:function(){console.warn("THREE.WebGLRenderer: .addPrePlugin() has been removed.")},addPostPlugin:function(){console.warn("THREE.WebGLRenderer: .addPostPlugin() has been removed.")},updateShadowMap:function(){console.warn("THREE.WebGLRenderer: .updateShadowMap() has been removed.")}});
-Object.defineProperties(Xd.prototype,{shadowMapEnabled:{get:function(){return this.shadowMap.enabled},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapEnabled is now .shadowMap.enabled.");this.shadowMap.enabled=a}},shadowMapType:{get:function(){return this.shadowMap.type},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapType is now .shadowMap.type.");this.shadowMap.type=a}},shadowMapCullFace:{get:function(){return this.shadowMap.cullFace},set:function(a){console.warn("THREE.WebGLRenderer: .shadowMapCullFace is now .shadowMap.cullFace.");
-this.shadowMap.cullFace=a}}});Object.defineProperties(Ie.prototype,{cullFace:{get:function(){return this.renderReverseSided?2:1},set:function(a){a=1!==a;console.warn("WebGLRenderer: .shadowMap.cullFace is deprecated. Set .shadowMap.renderReverseSided to "+a+".");this.renderReverseSided=a}}});Object.defineProperties(Cb.prototype,{wrapS:{get:function(){console.warn("THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.");return this.texture.wrapS},set:function(a){console.warn("THREE.WebGLRenderTarget: .wrapS is now .texture.wrapS.");
-this.texture.wrapS=a}},wrapT:{get:function(){console.warn("THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.");return this.texture.wrapT},set:function(a){console.warn("THREE.WebGLRenderTarget: .wrapT is now .texture.wrapT.");this.texture.wrapT=a}},magFilter:{get:function(){console.warn("THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.");return this.texture.magFilter},set:function(a){console.warn("THREE.WebGLRenderTarget: .magFilter is now .texture.magFilter.");this.texture.magFilter=
-a}},minFilter:{get:function(){console.warn("THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.");return this.texture.minFilter},set:function(a){console.warn("THREE.WebGLRenderTarget: .minFilter is now .texture.minFilter.");this.texture.minFilter=a}},anisotropy:{get:function(){console.warn("THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.");return this.texture.anisotropy},set:function(a){console.warn("THREE.WebGLRenderTarget: .anisotropy is now .texture.anisotropy.");this.texture.anisotropy=
-a}},offset:{get:function(){console.warn("THREE.WebGLRenderTarget: .offset is now .texture.offset.");return this.texture.offset},set:function(a){console.warn("THREE.WebGLRenderTarget: .offset is now .texture.offset.");this.texture.offset=a}},repeat:{get:function(){console.warn("THREE.WebGLRenderTarget: .repeat is now .texture.repeat.");return this.texture.repeat},set:function(a){console.warn("THREE.WebGLRenderTarget: .repeat is now .texture.repeat.");this.texture.repeat=a}},format:{get:function(){console.warn("THREE.WebGLRenderTarget: .format is now .texture.format.");
-return this.texture.format},set:function(a){console.warn("THREE.WebGLRenderTarget: .format is now .texture.format.");this.texture.format=a}},type:{get:function(){console.warn("THREE.WebGLRenderTarget: .type is now .texture.type.");return this.texture.type},set:function(a){console.warn("THREE.WebGLRenderTarget: .type is now .texture.type.");this.texture.type=a}},generateMipmaps:{get:function(){console.warn("THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.");return this.texture.generateMipmaps},
-set:function(a){console.warn("THREE.WebGLRenderTarget: .generateMipmaps is now .texture.generateMipmaps.");this.texture.generateMipmaps=a}}});hc.prototype.load=function(a){console.warn("THREE.Audio: .load has been deprecated. Use THREE.AudioLoader instead.");var b=this;(new fe).load(a,function(a){b.setBuffer(a)});return this};je.prototype.getData=function(){console.warn("THREE.AudioAnalyser: .getData() is now .getFrequencyData().");return this.getFrequencyData()};l.WebGLRenderTargetCube=Db;l.WebGLRenderTarget=
-Cb;l.WebGLRenderer=Xd;l.ShaderLib=$a;l.UniformsLib=R;l.UniformsUtils=Ca;l.ShaderChunk=X;l.FogExp2=Ib;l.Fog=Jb;l.Scene=ld;l.LensFlare=Yd;l.Sprite=xc;l.LOD=yc;l.SkinnedMesh=nd;l.Skeleton=zc;l.Bone=md;l.Mesh=la;l.LineSegments=Q;l.LineLoop=od;l.Line=sa;l.Points=Kb;l.Group=Ac;l.VideoTexture=pd;l.DataTexture=db;l.CompressedTexture=Lb;l.CubeTexture=Xa;l.CanvasTexture=qd;l.DepthTexture=Bc;l.Texture=ba;l.CompressedTextureLoader=Oe;l.DataTextureLoader=$d;l.CubeTextureLoader=ae;l.TextureLoader=rd;l.ObjectLoader=
-Pe;l.MaterialLoader=Gd;l.BufferGeometryLoader=be;l.DefaultLoadingManager=va;l.LoadingManager=Zd;l.JSONLoader=ce;l.ImageLoader=Sc;l.FontLoader=Re;l.FileLoader=Ka;l.Loader=ec;l.Cache=ed;l.AudioLoader=fe;l.SpotLightShadow=td;l.SpotLight=ud;l.PointLight=vd;l.RectAreaLight=zd;l.HemisphereLight=sd;l.DirectionalLightShadow=wd;l.DirectionalLight=xd;l.AmbientLight=yd;l.LightShadow=tb;l.Light=na;l.StereoCamera=Se;l.PerspectiveCamera=qa;l.OrthographicCamera=Fb;l.CubeCamera=Hd;l.ArrayCamera=kd;l.Camera=Na;l.AudioListener=
-ge;l.PositionalAudio=ie;l.AudioContext=he;l.AudioAnalyser=je;l.Audio=hc;l.VectorKeyframeTrack=cc;l.StringKeyframeTrack=Dd;l.QuaternionKeyframeTrack=Uc;l.NumberKeyframeTrack=dc;l.ColorKeyframeTrack=Fd;l.BooleanKeyframeTrack=Ed;l.PropertyMixer=ke;l.PropertyBinding=ha;l.KeyframeTrack=vb;l.AnimationUtils=ia;l.AnimationObjectGroup=Ue;l.AnimationMixer=We;l.AnimationClip=Da;l.Uniform=Id;l.InstancedBufferGeometry=le;l.BufferGeometry=E;l.GeometryIdCount=function(){return Rd++};l.Geometry=J;l.InterleavedBufferAttribute=
-me;l.InstancedInterleavedBuffer=ne;l.InterleavedBuffer=ic;l.InstancedBufferAttribute=oe;l.Face3=Sa;l.Object3D=z;l.Raycaster=Xe;l.Layers=Qd;l.EventDispatcher=xa;l.Clock=Ze;l.QuaternionLinearInterpolant=Cd;l.LinearInterpolant=Tc;l.DiscreteInterpolant=Bd;l.CubicInterpolant=Ad;l.Interpolant=wa;l.Triangle=Ta;l.Math=Y;l.Spherical=$e;l.Cylindrical=af;l.Plane=Aa;l.Frustum=gd;l.Sphere=Ea;l.Ray=kb;l.Matrix4=K;l.Matrix3=Ba;l.Box3=Ra;l.Box2=fd;l.Line3=Hb;l.Euler=ab;l.Vector4=fa;l.Vector3=n;l.Vector2=C;l.Quaternion=
-oa;l.Color=G;l.MorphBlendMesh=ta;l.ImmediateRenderObject=Xc;l.VertexNormalsHelper=Yc;l.SpotLightHelper=jc;l.SkeletonHelper=kc;l.PointLightHelper=lc;l.RectAreaLightHelper=mc;l.HemisphereLightHelper=nc;l.GridHelper=Zc;l.PolarGridHelper=Jd;l.FaceNormalsHelper=$c;l.DirectionalLightHelper=oc;l.CameraHelper=ad;l.BoxHelper=Ab;l.ArrowHelper=Bb;l.AxisHelper=Ld;l.CatmullRomCurve3=La;l.CubicBezierCurve3=bd;l.QuadraticBezierCurve3=cd;l.LineCurve3=dd;l.ArcCurve=Md;l.EllipseCurve=Va;l.SplineCurve=yb;l.CubicBezierCurve=
-fc;l.QuadraticBezierCurve=gc;l.LineCurve=Qa;l.Shape=zb;l.Path=Wc;l.ShapePath=de;l.Font=ee;l.CurvePath=Vc;l.Curve=ua;l.ShapeUtils=Ia;l.SceneUtils={createMultiMaterialObject:function(a,b){for(var c=new Ac,d=0,e=b.length;d<e;d++)c.add(new la(a,b[d]));return c},detach:function(a,b,c){a.applyMatrix(b.matrixWorld);b.remove(a);c.add(a)},attach:function(a,b,c){a.applyMatrix((new K).getInverse(c.matrixWorld));b.remove(a);c.add(a)}};l.WireframeGeometry=Mb;l.ParametricGeometry=Cc;l.ParametricBufferGeometry=
-Nb;l.TetrahedronGeometry=Ec;l.TetrahedronBufferGeometry=Ob;l.OctahedronGeometry=Fc;l.OctahedronBufferGeometry=lb;l.IcosahedronGeometry=Gc;l.IcosahedronBufferGeometry=Pb;l.DodecahedronGeometry=Hc;l.DodecahedronBufferGeometry=Qb;l.PolyhedronGeometry=Dc;l.PolyhedronBufferGeometry=za;l.TubeGeometry=Ic;l.TubeBufferGeometry=Rb;l.TorusKnotGeometry=Jc;l.TorusKnotBufferGeometry=Sb;l.TorusGeometry=Kc;l.TorusBufferGeometry=Tb;l.TextGeometry=Lc;l.TextBufferGeometry=Ub;l.SphereGeometry=Mc;l.SphereBufferGeometry=
-mb;l.RingGeometry=Nc;l.RingBufferGeometry=Vb;l.PlaneGeometry=vc;l.PlaneBufferGeometry=jb;l.LatheGeometry=Oc;l.LatheBufferGeometry=Wb;l.ShapeGeometry=Xb;l.ShapeBufferGeometry=Yb;l.ExtrudeGeometry=cb;l.ExtrudeBufferGeometry=Ga;l.EdgesGeometry=Zb;l.ConeGeometry=Pc;l.ConeBufferGeometry=Qc;l.CylinderGeometry=nb;l.CylinderBufferGeometry=Ua;l.CircleGeometry=Rc;l.CircleBufferGeometry=$b;l.BoxGeometry=Gb;l.BoxBufferGeometry=ib;l.ShadowMaterial=ac;l.SpriteMaterial=bb;l.RawShaderMaterial=bc;l.ShaderMaterial=
-ra;l.PointsMaterial=Fa;l.MeshPhysicalMaterial=ob;l.MeshStandardMaterial=Pa;l.MeshPhongMaterial=Ja;l.MeshToonMaterial=pb;l.MeshNormalMaterial=qb;l.MeshLambertMaterial=rb;l.MeshDepthMaterial=Za;l.MeshBasicMaterial=ya;l.LineDashedMaterial=sb;l.LineBasicMaterial=ea;l.Material=U;l.Float64BufferAttribute=uc;l.Float32BufferAttribute=B;l.Uint32BufferAttribute=hb;l.Int32BufferAttribute=tc;l.Uint16BufferAttribute=gb;l.Int16BufferAttribute=sc;l.Uint8ClampedBufferAttribute=rc;l.Uint8BufferAttribute=qc;l.Int8BufferAttribute=
-pc;l.BufferAttribute=Z;l.REVISION="86";l.MOUSE={LEFT:0,MIDDLE:1,RIGHT:2};l.CullFaceNone=0;l.CullFaceBack=1;l.CullFaceFront=2;l.CullFaceFrontBack=3;l.FrontFaceDirectionCW=0;l.FrontFaceDirectionCCW=1;l.BasicShadowMap=0;l.PCFShadowMap=1;l.PCFSoftShadowMap=2;l.FrontSide=0;l.BackSide=1;l.DoubleSide=2;l.FlatShading=1;l.SmoothShading=2;l.NoColors=0;l.FaceColors=1;l.VertexColors=2;l.NoBlending=0;l.NormalBlending=1;l.AdditiveBlending=2;l.SubtractiveBlending=3;l.MultiplyBlending=4;l.CustomBlending=5;l.AddEquation=
-100;l.SubtractEquation=101;l.ReverseSubtractEquation=102;l.MinEquation=103;l.MaxEquation=104;l.ZeroFactor=200;l.OneFactor=201;l.SrcColorFactor=202;l.OneMinusSrcColorFactor=203;l.SrcAlphaFactor=204;l.OneMinusSrcAlphaFactor=205;l.DstAlphaFactor=206;l.OneMinusDstAlphaFactor=207;l.DstColorFactor=208;l.OneMinusDstColorFactor=209;l.SrcAlphaSaturateFactor=210;l.NeverDepth=0;l.AlwaysDepth=1;l.LessDepth=2;l.LessEqualDepth=3;l.EqualDepth=4;l.GreaterEqualDepth=5;l.GreaterDepth=6;l.NotEqualDepth=7;l.MultiplyOperation=
-0;l.MixOperation=1;l.AddOperation=2;l.NoToneMapping=0;l.LinearToneMapping=1;l.ReinhardToneMapping=2;l.Uncharted2ToneMapping=3;l.CineonToneMapping=4;l.UVMapping=300;l.CubeReflectionMapping=301;l.CubeRefractionMapping=302;l.EquirectangularReflectionMapping=303;l.EquirectangularRefractionMapping=304;l.SphericalReflectionMapping=305;l.CubeUVReflectionMapping=306;l.CubeUVRefractionMapping=307;l.RepeatWrapping=1E3;l.ClampToEdgeWrapping=1001;l.MirroredRepeatWrapping=1002;l.NearestFilter=1003;l.NearestMipMapNearestFilter=
-1004;l.NearestMipMapLinearFilter=1005;l.LinearFilter=1006;l.LinearMipMapNearestFilter=1007;l.LinearMipMapLinearFilter=1008;l.UnsignedByteType=1009;l.ByteType=1010;l.ShortType=1011;l.UnsignedShortType=1012;l.IntType=1013;l.UnsignedIntType=1014;l.FloatType=1015;l.HalfFloatType=1016;l.UnsignedShort4444Type=1017;l.UnsignedShort5551Type=1018;l.UnsignedShort565Type=1019;l.UnsignedInt248Type=1020;l.AlphaFormat=1021;l.RGBFormat=1022;l.RGBAFormat=1023;l.LuminanceFormat=1024;l.LuminanceAlphaFormat=1025;l.RGBEFormat=
-1023;l.DepthFormat=1026;l.DepthStencilFormat=1027;l.RGB_S3TC_DXT1_Format=2001;l.RGBA_S3TC_DXT1_Format=2002;l.RGBA_S3TC_DXT3_Format=2003;l.RGBA_S3TC_DXT5_Format=2004;l.RGB_PVRTC_4BPPV1_Format=2100;l.RGB_PVRTC_2BPPV1_Format=2101;l.RGBA_PVRTC_4BPPV1_Format=2102;l.RGBA_PVRTC_2BPPV1_Format=2103;l.RGB_ETC1_Format=2151;l.LoopOnce=2200;l.LoopRepeat=2201;l.LoopPingPong=2202;l.InterpolateDiscrete=2300;l.InterpolateLinear=2301;l.InterpolateSmooth=2302;l.ZeroCurvatureEnding=2400;l.ZeroSlopeEnding=2401;l.WrapAroundEnding=
-2402;l.TrianglesDrawMode=0;l.TriangleStripDrawMode=1;l.TriangleFanDrawMode=2;l.LinearEncoding=3E3;l.sRGBEncoding=3001;l.GammaEncoding=3007;l.RGBEEncoding=3002;l.LogLuvEncoding=3003;l.RGBM7Encoding=3004;l.RGBM16Encoding=3005;l.RGBDEncoding=3006;l.BasicDepthPacking=3200;l.RGBADepthPacking=3201;l.CubeGeometry=Gb;l.Face4=function(a,b,c,d,e,f,g){console.warn("THREE.Face4 has been removed. A THREE.Face3 will be created instead.");return new Sa(a,b,c,e,f,g)};l.LineStrip=0;l.LinePieces=1;l.MeshFaceMaterial=
-function(a){console.warn("THREE.MeshFaceMaterial has been removed. Use an Array instead.");return a};l.MultiMaterial=function(a){void 0===a&&(a=[]);console.warn("THREE.MultiMaterial has been removed. Use an Array instead.");a.isMultiMaterial=!0;a.materials=a;a.clone=function(){return a.slice()};return a};l.PointCloud=function(a,b){console.warn("THREE.PointCloud has been renamed to THREE.Points.");return new Kb(a,b)};l.Particle=function(a){console.warn("THREE.Particle has been renamed to THREE.Sprite.");
-return new xc(a)};l.ParticleSystem=function(a,b){console.warn("THREE.ParticleSystem has been renamed to THREE.Points.");return new Kb(a,b)};l.PointCloudMaterial=function(a){console.warn("THREE.PointCloudMaterial has been renamed to THREE.PointsMaterial.");return new Fa(a)};l.ParticleBasicMaterial=function(a){console.warn("THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.");return new Fa(a)};l.ParticleSystemMaterial=function(a){console.warn("THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.");
-return new Fa(a)};l.Vertex=function(a,b,c){console.warn("THREE.Vertex has been removed. Use THREE.Vector3 instead.");return new n(a,b,c)};l.DynamicBufferAttribute=function(a,b){console.warn("THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.");return(new Z(a,b)).setDynamic(!0)};l.Int8Attribute=function(a,b){console.warn("THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.");return new pc(a,b)};l.Uint8Attribute=
-function(a,b){console.warn("THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.");return new qc(a,b)};l.Uint8ClampedAttribute=function(a,b){console.warn("THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.");return new rc(a,b)};l.Int16Attribute=function(a,b){console.warn("THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.");return new sc(a,b)};l.Uint16Attribute=function(a,b){console.warn("THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.");
-return new gb(a,b)};l.Int32Attribute=function(a,b){console.warn("THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.");return new tc(a,b)};l.Uint32Attribute=function(a,b){console.warn("THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.");return new hb(a,b)};l.Float32Attribute=function(a,b){console.warn("THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.");return new B(a,b)};l.Float64Attribute=
-function(a,b){console.warn("THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.");return new uc(a,b)};l.ClosedSplineCurve3=cf;l.SplineCurve3=df;l.Spline=se;l.BoundingBoxHelper=function(a,b){console.warn("THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.");return new Ab(a,b)};l.EdgesHelper=function(a,b){console.warn("THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.");return new Q(new Zb(a.geometry),new ea({color:void 0!==
-b?b:16777215}))};l.WireframeHelper=function(a,b){console.warn("THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.");return new Q(new Mb(a.geometry),new ea({color:void 0!==b?b:16777215}))};l.XHRLoader=function(a){console.warn("THREE.XHRLoader has been renamed to THREE.FileLoader.");return new Ka(a)};l.BinaryTextureLoader=function(a){console.warn("THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.");return new $d(a)};l.GeometryUtils={merge:function(a,b,
-c){console.warn("THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.");var d;b.isMesh&&(b.matrixAutoUpdate&&b.updateMatrix(),d=b.matrix,b=b.geometry);a.merge(b,d,c)},center:function(a){console.warn("THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.");return a.center()}};l.ImageUtils={crossOrigin:void 0,loadTexture:function(a,b,c,d){console.warn("THREE.ImageUtils.loadTexture has been deprecated. Use THREE.TextureLoader() instead.");
-var e=new rd;e.setCrossOrigin(this.crossOrigin);a=e.load(a,c,void 0,d);b&&(a.mapping=b);return a},loadTextureCube:function(a,b,c,d){console.warn("THREE.ImageUtils.loadTextureCube has been deprecated. Use THREE.CubeTextureLoader() instead.");var e=new ae;e.setCrossOrigin(this.crossOrigin);a=e.load(a,c,void 0,d);b&&(a.mapping=b);return a},loadCompressedTexture:function(){console.error("THREE.ImageUtils.loadCompressedTexture has been removed. Use THREE.DDSLoader instead.")},loadCompressedTextureCube:function(){console.error("THREE.ImageUtils.loadCompressedTextureCube has been removed. Use THREE.DDSLoader instead.")}};
-l.Projector=function(){console.error("THREE.Projector has been moved to /examples/js/renderers/Projector.js.");this.projectVector=function(a,b){console.warn("THREE.Projector: .projectVector() is now vector.project().");a.project(b)};this.unprojectVector=function(a,b){console.warn("THREE.Projector: .unprojectVector() is now vector.unproject().");a.unproject(b)};this.pickingRay=function(){console.error("THREE.Projector: .pickingRay() is now raycaster.setFromCamera().")}};l.CanvasRenderer=function(){console.error("THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js");
-this.domElement=document.createElementNS("http://www.w3.org/1999/xhtml","canvas");this.clear=function(){};this.render=function(){};this.setClearColor=function(){};this.setSize=function(){}};Object.defineProperty(l,"__esModule",{value:!0})});
-//END FILE:  Three.js
-
-
-
-
-// BEGIN FILE:  OBJLoader.js
-/**
- * @author mrdoob / http://mrdoob.com/
- */
-
-
-THREE.OBJLoader = function ( manager ) {
-
-	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
-
-	this.materials = null;
-
-};
-
-THREE.OBJLoader.prototype = {
-
-	constructor: THREE.OBJLoader,
-
-	load: function ( url, onLoad, onProgress, onError ) {
-
-		var scope = this;
-
-		var loader = new THREE.FileLoader( scope.manager );
-		loader.setPath( this.path );
-		loader.load( url, function ( text ) {
-
-			onLoad( scope.parse( text ) );
-
-		}, onProgress, onError );
-
-	},
-
-	setPath: function ( value ) {
-
-		this.path = value;
-
-	},
-
-	setMaterials: function ( materials ) {
-
-		this.materials = materials;
-
-	},
-
-	parse: function ( text ) {
-
-		console.time( 'OBJLoader' );
-
-		var objects = [];
-		var object;
-		var foundObjects = false;
-		var vertices = [];
-		var normals = [];
-		var uvs = [];
-
-		function addObject( name ) {
-
-			var geometry = {
-				vertices: [],
-				normals: [],
-				uvs: []
-			};
-
-			var material = {
-				name: '',
-				smooth: true
-			};
-
-			object = {
-				name: name,
-				geometry: geometry,
-				material: material
-			};
-
-			objects.push( object );
-
-		}
-
-		function parseVertexIndex( value ) {
-
-			var index = parseInt( value );
-
-			return ( index >= 0 ? index - 1 : index + vertices.length / 3 ) * 3;
-
-		}
-
-		function parseNormalIndex( value ) {
-
-			var index = parseInt( value );
-
-			return ( index >= 0 ? index - 1 : index + normals.length / 3 ) * 3;
-
-		}
-
-		function parseUVIndex( value ) {
-
-			var index = parseInt( value );
-
-			return ( index >= 0 ? index - 1 : index + uvs.length / 2 ) * 2;
-
-		}
-
-		function addVertex( a, b, c ) {
-
-			object.geometry.vertices.push(
-				vertices[ a ], vertices[ a + 1 ], vertices[ a + 2 ],
-				vertices[ b ], vertices[ b + 1 ], vertices[ b + 2 ],
-				vertices[ c ], vertices[ c + 1 ], vertices[ c + 2 ]
-			);
-
-		}
-
-		function addNormal( a, b, c ) {
-
-			object.geometry.normals.push(
-				normals[ a ], normals[ a + 1 ], normals[ a + 2 ],
-				normals[ b ], normals[ b + 1 ], normals[ b + 2 ],
-				normals[ c ], normals[ c + 1 ], normals[ c + 2 ]
-			);
-
-		}
-
-		function addUV( a, b, c ) {
-
-			object.geometry.uvs.push(
-				uvs[ a ], uvs[ a + 1 ],
-				uvs[ b ], uvs[ b + 1 ],
-				uvs[ c ], uvs[ c + 1 ]
-			);
-
-		}
-
-		function addFace( a, b, c, d,  ua, ub, uc, ud, na, nb, nc, nd ) {
-
-			var ia = parseVertexIndex( a );
-			var ib = parseVertexIndex( b );
-			var ic = parseVertexIndex( c );
-			var id;
-
-			if ( d === undefined ) {
-
-				addVertex( ia, ib, ic );
-
-			} else {
-
-				id = parseVertexIndex( d );
-
-				addVertex( ia, ib, id );
-				addVertex( ib, ic, id );
-
-			}
-
-			if ( ua !== undefined ) {
-
-				ia = parseUVIndex( ua );
-				ib = parseUVIndex( ub );
-				ic = parseUVIndex( uc );
-
-				if ( d === undefined ) {
-
-					addUV( ia, ib, ic );
-
-				} else {
-
-					id = parseUVIndex( ud );
-
-					addUV( ia, ib, id );
-					addUV( ib, ic, id );
-
-				}
-
-			}
-
-			if ( na !== undefined ) {
-
-				ia = parseNormalIndex( na );
-				ib = parseNormalIndex( nb );
-				ic = parseNormalIndex( nc );
-
-				if ( d === undefined ) {
-
-					addNormal( ia, ib, ic );
-
-				} else {
-
-					id = parseNormalIndex( nd );
-
-					addNormal( ia, ib, id );
-					addNormal( ib, ic, id );
-
-				}
-
-			}
-
-		}
-
-		addObject( '' );
-
-		// v float float float
-		var vertex_pattern = /^v\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/;
-
-		// vn float float float
-		var normal_pattern = /^vn\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/;
-
-		// vt float float
-		var uv_pattern = /^vt\s+([\d|\.|\+|\-|e|E]+)\s+([\d|\.|\+|\-|e|E]+)/;
-
-		// f vertex vertex vertex ...
-		var face_pattern1 = /^f\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)(?:\s+(-?\d+))?/;
-
-		// f vertex/uv vertex/uv vertex/uv ...
-		var face_pattern2 = /^f\s+((-?\d+)\/(-?\d+))\s+((-?\d+)\/(-?\d+))\s+((-?\d+)\/(-?\d+))(?:\s+((-?\d+)\/(-?\d+)))?/;
-
-		// f vertex/uv/normal vertex/uv/normal vertex/uv/normal ...
-		var face_pattern3 = /^f\s+((-?\d+)\/(-?\d+)\/(-?\d+))\s+((-?\d+)\/(-?\d+)\/(-?\d+))\s+((-?\d+)\/(-?\d+)\/(-?\d+))(?:\s+((-?\d+)\/(-?\d+)\/(-?\d+)))?/;
-
-		// f vertex//normal vertex//normal vertex//normal ...
-		var face_pattern4 = /^f\s+((-?\d+)\/\/(-?\d+))\s+((-?\d+)\/\/(-?\d+))\s+((-?\d+)\/\/(-?\d+))(?:\s+((-?\d+)\/\/(-?\d+)))?/;
-
-		var object_pattern = /^[og]\s+(.+)/;
-
-		var smoothing_pattern = /^s\s+(\d+|on|off)/;
-
-		//
-
-		var lines = text.split( '\n' );
-
-		for ( var i = 0; i < lines.length; i ++ ) {
-
-			var line = lines[ i ];
-			line = line.trim();
-
-			var result;
-
-			if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
-
-				continue;
-
-			} else if ( ( result = vertex_pattern.exec( line ) ) !== null ) {
-
-				// ["v 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
-
-				vertices.push(
-					parseFloat( result[ 1 ] ),
-					parseFloat( result[ 2 ] ),
-					parseFloat( result[ 3 ] )
-				);
-
-			} else if ( ( result = normal_pattern.exec( line ) ) !== null ) {
-
-				// ["vn 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
-
-				normals.push(
-					parseFloat( result[ 1 ] ),
-					parseFloat( result[ 2 ] ),
-					parseFloat( result[ 3 ] )
-				);
-
-			} else if ( ( result = uv_pattern.exec( line ) ) !== null ) {
-
-				// ["vt 0.1 0.2", "0.1", "0.2"]
-
-				uvs.push(
-					parseFloat( result[ 1 ] ),
-					parseFloat( result[ 2 ] )
-				);
-
-			} else if ( ( result = face_pattern1.exec( line ) ) !== null ) {
-
-				// ["f 1 2 3", "1", "2", "3", undefined]
-
-				addFace(
-					result[ 1 ], result[ 2 ], result[ 3 ], result[ 4 ]
-				);
-
-			} else if ( ( result = face_pattern2.exec( line ) ) !== null ) {
-
-				// ["f 1/1 2/2 3/3", " 1/1", "1", "1", " 2/2", "2", "2", " 3/3", "3", "3", undefined, undefined, undefined]
-
-				addFace(
-					result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ],
-					result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ]
-				);
-
-			} else if ( ( result = face_pattern3.exec( line ) ) !== null ) {
-
-				// ["f 1/1/1 2/2/2 3/3/3", " 1/1/1", "1", "1", "1", " 2/2/2", "2", "2", "2", " 3/3/3", "3", "3", "3", undefined, undefined, undefined, undefined]
-
-				addFace(
-					result[ 2 ], result[ 6 ], result[ 10 ], result[ 14 ],
-					result[ 3 ], result[ 7 ], result[ 11 ], result[ 15 ],
-					result[ 4 ], result[ 8 ], result[ 12 ], result[ 16 ]
-				);
-
-			} else if ( ( result = face_pattern4.exec( line ) ) !== null ) {
-
-				// ["f 1//1 2//2 3//3", " 1//1", "1", "1", " 2//2", "2", "2", " 3//3", "3", "3", undefined, undefined, undefined]
-
-				addFace(
-					result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ],
-					undefined, undefined, undefined, undefined,
-					result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ]
-				);
-
-			} else if ( ( result = object_pattern.exec( line ) ) !== null ) {
-
-				// o object_name
-				// or
-				// g group_name
-
-				var name = result[ 1 ].trim();
-
-				if ( foundObjects === false ) {
-
-					foundObjects = true;
-					object.name = name;
-
-				} else {
-
-					addObject( name );
-
-				}
-
-			} else if ( /^usemtl /.test( line ) ) {
-
-				// material
-
-				object.material.name = line.substring( 7 ).trim();
-
-			} else if ( /^mtllib /.test( line ) ) {
-
-				// mtl file
-
-			} else if ( ( result = smoothing_pattern.exec( line ) ) !== null ) {
-
-				// smooth shading
-
-				object.material.smooth = result[ 1 ] === "1" || result[ 1 ] === "on";
-
-			} else {
-
-				throw new Error( "Unexpected line: " + line );
-
-			}
-
-		}
-
-		var container = new THREE.Group();
-
-		for ( var i = 0, l = objects.length; i < l; i ++ ) {
-
-			object = objects[ i ];
-			var geometry = object.geometry;
-
-			var buffergeometry = new THREE.BufferGeometry();
-
-			buffergeometry.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array( geometry.vertices ), 3 ) );
-
-			if ( geometry.normals.length > 0 ) {
-
-				buffergeometry.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( geometry.normals ), 3 ) );
-
-			} else {
-
-				buffergeometry.computeVertexNormals();
-
-			}
-
-			if ( geometry.uvs.length > 0 ) {
-
-				buffergeometry.addAttribute( 'uv', new THREE.BufferAttribute( new Float32Array( geometry.uvs ), 2 ) );
-
-			}
-
-			var material;
-
-			if ( this.materials !== null ) {
-
-				material = this.materials.create( object.material.name );
-
-			}
-
-			if ( !material ) {
-
-				material = new THREE.MeshPhongMaterial();
-				material.name = object.material.name;
-
-			}
-
-			material.shading = object.material.smooth ? THREE.SmoothShading : THREE.FlatShading;
-
-			var mesh = new THREE.Mesh( buffergeometry, material );
-			mesh.name = object.name;
-
-			container.add( mesh );
-
-		}
-
-		console.timeEnd( 'OBJLoader' );
-
-		return container;
-
-	}
-
-};
-
-// END FILE:  OBJLoader.js
-
-
-// BEGIN FILE:  MTLLoader.js 
-/**
- * Loads a Wavefront .mtl file specifying materials
- *
- * @author angelxuanchang
- */
-
-THREE.MTLLoader = function( manager ) {
-
-	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
-
-};
-
-THREE.MTLLoader.prototype = {
-
-	constructor: THREE.MTLLoader,
-
-	load: function ( url, onLoad, onProgress, onError ) {
-
-		var scope = this;
-
-		var loader = new THREE.FileLoader( this.manager );
-		loader.setPath( this.path );
-		loader.load( url, function ( text ) {
-
-			onLoad( scope.parse( text ) );
-
-		}, onProgress, onError );
-
-	},
-
-	setPath: function ( value ) {
-
-		this.path = value;
-
-	},
-
-	setBaseUrl: function( value ) {
-
-		// TODO: Merge with setPath()? Or rename to setTexturePath?
-
-		this.baseUrl = value;
-
-	},
-
-	setCrossOrigin: function ( value ) {
-
-		this.crossOrigin = value;
-
-	},
-
-	setMaterialOptions: function ( value ) {
-
-		this.materialOptions = value;
-
-	},
-
-	/**
-	 * Parses loaded MTL file
-	 * @param text - Content of MTL file
-	 * @return {THREE.MTLLoader.MaterialCreator}
-	 */
-	parse: function ( text ) {
-
-		var lines = text.split( "\n" );
-		var info = {};
-		var delimiter_pattern = /\s+/;
-		var materialsInfo = {};
-
-		for ( var i = 0; i < lines.length; i ++ ) {
-
-			var line = lines[ i ];
-			line = line.trim();
-
-			if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
-
-				// Blank line or comment ignore
-				continue;
-
-			}
-
-			var pos = line.indexOf( ' ' );
-
-			var key = ( pos >= 0 ) ? line.substring( 0, pos ) : line;
-			key = key.toLowerCase();
-
-			var value = ( pos >= 0 ) ? line.substring( pos + 1 ) : "";
-			value = value.trim();
-
-			if ( key === "newmtl" ) {
-
-				// New material
-
-				info = { name: value };
-				materialsInfo[ value ] = info;
-
-			} else if ( info ) {
-
-				if ( key === "ka" || key === "kd" || key === "ks" ) {
-
-					var ss = value.split( delimiter_pattern, 3 );
-					info[ key ] = [ parseFloat( ss[ 0 ] ), parseFloat( ss[ 1 ] ), parseFloat( ss[ 2 ] ) ];
-
-				} else {
-
-					info[ key ] = value;
-
-				}
-
-			}
-
-		}
-
-		var materialCreator = new THREE.MTLLoader.MaterialCreator( this.baseUrl, this.materialOptions );
-		materialCreator.setCrossOrigin( this.crossOrigin );
-		materialCreator.setManager( this.manager );
-		materialCreator.setMaterials( materialsInfo );
-		return materialCreator;
-
-	}
-
-};
-
-/**
- * Create a new THREE-MTLLoader.MaterialCreator
- * @param baseUrl - Url relative to which textures are loaded
- * @param options - Set of options on how to construct the materials
- *                  side: Which side to apply the material
- *                        THREE.FrontSide (default), THREE.BackSide, THREE.DoubleSide
- *                  wrap: What type of wrapping to apply for textures
- *                        THREE.RepeatWrapping (default), THREE.ClampToEdgeWrapping, THREE.MirroredRepeatWrapping
- *                  normalizeRGB: RGBs need to be normalized to 0-1 from 0-255
- *                                Default: false, assumed to be already normalized
- *                  ignoreZeroRGBs: Ignore values of RGBs (Ka,Kd,Ks) that are all 0's
- *                                  Default: false
- * @constructor
- */
-
-THREE.MTLLoader.MaterialCreator = function( baseUrl, options ) {
-
-	this.baseUrl = baseUrl;
-	this.options = options;
-	this.materialsInfo = {};
-	this.materials = {};
-	this.materialsArray = [];
-	this.nameLookup = {};
-
-	this.side = ( this.options && this.options.side ) ? this.options.side : THREE.FrontSide;
-	this.wrap = ( this.options && this.options.wrap ) ? this.options.wrap : THREE.RepeatWrapping;
-
-};
-
-THREE.MTLLoader.MaterialCreator.prototype = {
-
-	constructor: THREE.MTLLoader.MaterialCreator,
-
-	setCrossOrigin: function ( value ) {
-
-		this.crossOrigin = value;
-
-	},
-
-	setManager: function ( value ) {
-
-		this.manager = value;
-
-	},
-
-	setMaterials: function( materialsInfo ) {
-
-		this.materialsInfo = this.convert( materialsInfo );
-		this.materials = {};
-		this.materialsArray = [];
-		this.nameLookup = {};
-
-	},
-
-	convert: function( materialsInfo ) {
-
-		if ( ! this.options ) return materialsInfo;
-
-		var converted = {};
-
-		for ( var mn in materialsInfo ) {
-
-			// Convert materials info into normalized form based on options
-
-			var mat = materialsInfo[ mn ];
-
-			var covmat = {};
-
-			converted[ mn ] = covmat;
-
-			for ( var prop in mat ) {
-
-				var save = true;
-				var value = mat[ prop ];
-				var lprop = prop.toLowerCase();
-
-				switch ( lprop ) {
-
-					case 'kd':
-					case 'ka':
-					case 'ks':
-
-						// Diffuse color (color under white light) using RGB values
-
-						if ( this.options && this.options.normalizeRGB ) {
-
-							value = [ value[ 0 ] / 255, value[ 1 ] / 255, value[ 2 ] / 255 ];
-
-						}
-
-						if ( this.options && this.options.ignoreZeroRGBs ) {
-
-							if ( value[ 0 ] === 0 && value[ 1 ] === 0 && value[ 1 ] === 0 ) {
-
-								// ignore
-
-								save = false;
-
-							}
-
-						}
-
-						break;
-
-					default:
-
-						break;
-				}
-
-				if ( save ) {
-
-					covmat[ lprop ] = value;
-
-				}
-
-			}
-
-		}
-
-		return converted;
-
-	},
-
-	preload: function () {
-
-		for ( var mn in this.materialsInfo ) {
-
-			this.create( mn );
-
-		}
-
-	},
-
-	getIndex: function( materialName ) {
-
-		return this.nameLookup[ materialName ];
-
-	},
-
-	getAsArray: function() {
-
-		var index = 0;
-
-		for ( var mn in this.materialsInfo ) {
-
-			this.materialsArray[ index ] = this.create( mn );
-			this.nameLookup[ mn ] = index;
-			index ++;
-
-		}
-
-		return this.materialsArray;
-
-	},
-
-	create: function ( materialName ) {
-
-		if ( this.materials[ materialName ] === undefined ) {
-
-			this.createMaterial_( materialName );
-
-		}
-
-		return this.materials[ materialName ];
-
-	},
-
-	createMaterial_: function ( materialName ) {
-
-		// Create material
-
-		var mat = this.materialsInfo[ materialName ];
-		var params = {
-
-			name: materialName,
-			side: this.side
-
-		};
-
-		for ( var prop in mat ) {
-
-			var value = mat[ prop ];
-
-			if ( value === '' ) continue;
-
-			switch ( prop.toLowerCase() ) {
-
-				// Ns is material specular exponent
-
-				case 'kd':
-
-					// Diffuse color (color under white light) using RGB values
-
-					params[ 'color' ] = new THREE.Color().fromArray( value );
-
-					break;
-
-				case 'ks':
-
-					// Specular color (color when light is reflected from shiny surface) using RGB values
-					params[ 'specular' ] = new THREE.Color().fromArray( value );
-
-					break;
-
-				case 'map_kd':
-
-					// Diffuse texture map
-
-					params[ 'map' ] = this.loadTexture( this.baseUrl + value );
-					params[ 'map' ].wrapS = this.wrap;
-					params[ 'map' ].wrapT = this.wrap;
-
-					break;
-
-				case 'ns':
-
-					// The specular exponent (defines the focus of the specular highlight)
-					// A high exponent results in a tight, concentrated highlight. Ns values normally range from 0 to 1000.
-
-					params[ 'shininess' ] = parseFloat( value );
-
-					break;
-
-				case 'd':
-
-					if ( value < 1 ) {
-
-						params[ 'opacity' ] = value;
-						params[ 'transparent' ] = true;
-
-					}
-
-					break;
-
-				case 'Tr':
-
-					if ( value > 0 ) {
-
-						params[ 'opacity' ] = 1 - value;
-						params[ 'transparent' ] = true;
-
-					}
-
-					break;
-
-				case 'map_bump':
-				case 'bump':
-
-					// Bump texture map
-
-					if ( params[ 'bumpMap' ] ) break; // Avoid loading twice.
-
-					params[ 'bumpMap' ] = this.loadTexture( this.baseUrl + value );
-					params[ 'bumpMap' ].wrapS = this.wrap;
-					params[ 'bumpMap' ].wrapT = this.wrap;
-
-					break;
-
-				default:
-					break;
-
-			}
-
-		}
-
-		this.materials[ materialName ] = new THREE.MeshPhongMaterial( params );
-		return this.materials[ materialName ];
-
-	},
-
-
-	loadTexture: function ( url, mapping, onLoad, onProgress, onError ) {
-
-		var texture;
-		var loader = THREE.Loader.Handlers.get( url );
-		var manager = ( this.manager !== undefined ) ? this.manager : THREE.DefaultLoadingManager;
-
-		if ( loader === null ) {
-
-			loader = new THREE.TextureLoader( manager );
-
-		}
-
-		if ( loader.setCrossOrigin ) loader.setCrossOrigin( this.crossOrigin );
-		texture = loader.load( url, onLoad, onProgress, onError );
-
-		if ( mapping !== undefined ) texture.mapping = mapping;
-
-		return texture;
-
-	}
-
-};
-
-THREE.EventDispatcher.apply( THREE.MTLLoader.prototype );
-
-// END FILE:  MTLLoader.js
-
-
-// BEGIN FILE:  OBJMTLLoader.js
-/**
- * Loads a Wavefront .obj file with materials
- *
- * @author mrdoob / http://mrdoob.com/
- * @author angelxuanchang
- */
-
-THREE.OBJMTLLoader = function ( manager ) {
-
-	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
-
-};
-
-THREE.OBJMTLLoader.prototype = {
-
-	constructor: THREE.OBJMTLLoader,
-
-	load: function ( url, mtlurl, onLoad, onProgress, onError ) {
-
-		var scope = this;
-
-		var mtlLoader = new THREE.MTLLoader( scope.manager );
-		mtlLoader.crossOrigin = scope.crossOrigin;
-		mtlLoader.baseUrl = url.substr( 0, url.lastIndexOf( "/" ) + 1 );
-		mtlLoader.load( mtlurl, function ( materials ) {
-
-			var materialsCreator = materials;
-			materialsCreator.preload();
-
-			var loader = new THREE.FileLoader( scope.manager );
-      loader.crossOrigin = scope.crossOrigin;
-			loader.load( url, function ( text ) {
-
-				var object = scope.parse( text );
-
-				object.traverse( function ( object ) {
-
-					if ( object instanceof THREE.Mesh ) {
-
-						if ( object.material.name ) {
-
-							var material = materialsCreator.create( object.material.name );
-
-							if ( material ) object.material = material;
-
-						}
-
-					}
-
-				} );
-
-				onLoad( object );
-
-			}, onProgress, onError );
-
-		}, onProgress, onError );
-
-	},
-
-	/**
-	 * Parses loaded .obj file
-	 * @param data - content of .obj file
-	 * @param mtllibCallback - callback to handle mtllib declaration (optional)
-	 * @return {THREE.Object3D} - Object3D (with default material)
-	 */
-
-	parse: function ( data, mtllibCallback ) {
-
-		function vector( x, y, z ) {
-
-			return new THREE.Vector3( x, y, z );
-
-		}
-
-		function uv( u, v ) {
-
-			return new THREE.Vector2( u, v );
-
-		}
-
-		function face3( a, b, c, normals ) {
-
-			return new THREE.Face3( a, b, c, normals );
-
-		}
-
-		var face_offset = 0;
-
-		function meshN( meshName, materialName ) {
-
-			if ( vertices.length > 0 ) {
-
-				geometry.vertices = vertices;
-
-				geometry.mergeVertices();
-				geometry.computeFaceNormals();
-				geometry.computeBoundingSphere();
-
-				object.add( mesh );
-
-				geometry = new THREE.Geometry();
-				mesh = new THREE.Mesh( geometry, material );
-
-			}
-
-			if ( meshName !== undefined ) mesh.name = meshName;
-
-			if ( materialName !== undefined ) {
-
-				material = new THREE.MeshLambertMaterial();
-				material.name = materialName;
-
-				mesh.material = material;
-
-			}
-
-		}
-
-		var group = new THREE.Group();
-		var object = group;
-
-		var geometry = new THREE.Geometry();
-		var material = new THREE.MeshLambertMaterial();
-		var mesh = new THREE.Mesh( geometry, material );
-
-		var vertices = [];
-		var normals = [];
-		var uvs = [];
-
-		function add_face( a, b, c, normals_inds ) {
-
-			if ( normals_inds === undefined ) {
-
-				geometry.faces.push( face3(
-					parseInt( a ) - (face_offset + 1),
-					parseInt( b ) - (face_offset + 1),
-					parseInt( c ) - (face_offset + 1)
-				) );
-
-			} else {
-
-				geometry.faces.push( face3(
-					parseInt( a ) - (face_offset + 1),
-					parseInt( b ) - (face_offset + 1),
-					parseInt( c ) - (face_offset + 1),
-					[
-						normals[ parseInt( normals_inds[ 0 ] ) - 1 ].clone(),
-						normals[ parseInt( normals_inds[ 1 ] ) - 1 ].clone(),
-						normals[ parseInt( normals_inds[ 2 ] ) - 1 ].clone()
-					]
-				) );
-
-			}
-
-		}
-
-		function add_uvs( a, b, c ) {
-
-			geometry.faceVertexUvs[ 0 ].push( [
-				uvs[ parseInt( a ) - 1 ].clone(),
-				uvs[ parseInt( b ) - 1 ].clone(),
-				uvs[ parseInt( c ) - 1 ].clone()
-			] );
-
-		}
-
-		function handle_face_line(faces, uvs, normals_inds) {
-
-			if ( faces[ 3 ] === undefined ) {
-
-				add_face( faces[ 0 ], faces[ 1 ], faces[ 2 ], normals_inds );
-
-				if (!(uvs === undefined) && uvs.length > 0) {
-					add_uvs( uvs[ 0 ], uvs[ 1 ], uvs[ 2 ] );
-				}
-
-			} else {
-
-				if (!(normals_inds === undefined) && normals_inds.length > 0) {
-
-					add_face( faces[ 0 ], faces[ 1 ], faces[ 3 ], [ normals_inds[ 0 ], normals_inds[ 1 ], normals_inds[ 3 ] ]);
-					add_face( faces[ 1 ], faces[ 2 ], faces[ 3 ], [ normals_inds[ 1 ], normals_inds[ 2 ], normals_inds[ 3 ] ]);
-
-				} else {
-
-					add_face( faces[ 0 ], faces[ 1 ], faces[ 3 ]);
-					add_face( faces[ 1 ], faces[ 2 ], faces[ 3 ]);
-
-				}
-
-				if (!(uvs === undefined) && uvs.length > 0) {
-
-					add_uvs( uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] );
-					add_uvs( uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] );
-
-				}
-
-			}
-
-		}
-
-
-		// v float float float
-
-		var vertex_pattern = /v( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)/;
-
-		// vn float float float
-
-		var normal_pattern = /vn( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)/;
-
-		// vt float float
-
-		var uv_pattern = /vt( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)/;
-
-		// f vertex vertex vertex ...
-
-		var face_pattern1 = /f( +\d+)( +\d+)( +\d+)( +\d+)?/;
-
-		// f vertex/uv vertex/uv vertex/uv ...
-
-		var face_pattern2 = /f( +(\d+)\/(\d+))( +(\d+)\/(\d+))( +(\d+)\/(\d+))( +(\d+)\/(\d+))?/;
-
-		// f vertex/uv/normal vertex/uv/normal vertex/uv/normal ...
-
-		var face_pattern3 = /f( +(\d+)\/(\d+)\/(\d+))( +(\d+)\/(\d+)\/(\d+))( +(\d+)\/(\d+)\/(\d+))( +(\d+)\/(\d+)\/(\d+))?/;
-
-		// f vertex//normal vertex//normal vertex//normal ...
-
-		var face_pattern4 = /f( +(\d+)\/\/(\d+))( +(\d+)\/\/(\d+))( +(\d+)\/\/(\d+))( +(\d+)\/\/(\d+))?/
-
-		//
-
-		var lines = data.split( "\n" );
-
-		for ( var i = 0; i < lines.length; i ++ ) {
-
-			var line = lines[ i ];
-			line = line.trim();
-
-			var result;
-
-			if ( line.length === 0 || line.charAt( 0 ) === '#' ) {
-
-				continue;
-
-			} else if ( ( result = vertex_pattern.exec( line ) ) !== null ) {
-
-				// ["v 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
-
-				vertices.push( vector(
-					parseFloat( result[ 1 ] ),
-					parseFloat( result[ 2 ] ),
-					parseFloat( result[ 3 ] )
-				) );
-
-			} else if ( ( result = normal_pattern.exec( line ) ) !== null ) {
-
-				// ["vn 1.0 2.0 3.0", "1.0", "2.0", "3.0"]
-
-				normals.push( vector(
-					parseFloat( result[ 1 ] ),
-					parseFloat( result[ 2 ] ),
-					parseFloat( result[ 3 ] )
-				) );
-
-			} else if ( ( result = uv_pattern.exec( line ) ) !== null ) {
-
-				// ["vt 0.1 0.2", "0.1", "0.2"]
-
-				uvs.push( uv(
-					parseFloat( result[ 1 ] ),
-					parseFloat( result[ 2 ] )
-				) );
-
-			} else if ( ( result = face_pattern1.exec( line ) ) !== null ) {
-
-				// ["f 1 2 3", "1", "2", "3", undefined]
-
-				handle_face_line([ result[ 1 ], result[ 2 ], result[ 3 ], result[ 4 ] ]);
-
-			} else if ( ( result = face_pattern2.exec( line ) ) !== null ) {
-
-				// ["f 1/1 2/2 3/3", " 1/1", "1", "1", " 2/2", "2", "2", " 3/3", "3", "3", undefined, undefined, undefined]
-
-				handle_face_line(
-					[ result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ] ], //faces
-					[ result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ] ] //uv
-				);
-
-			} else if ( ( result = face_pattern3.exec( line ) ) !== null ) {
-
-				// ["f 1/1/1 2/2/2 3/3/3", " 1/1/1", "1", "1", "1", " 2/2/2", "2", "2", "2", " 3/3/3", "3", "3", "3", undefined, undefined, undefined, undefined]
-
-				handle_face_line(
-					[ result[ 2 ], result[ 6 ], result[ 10 ], result[ 14 ] ], //faces
-					[ result[ 3 ], result[ 7 ], result[ 11 ], result[ 15 ] ], //uv
-					[ result[ 4 ], result[ 8 ], result[ 12 ], result[ 16 ] ] //normal
-				);
-
-			} else if ( ( result = face_pattern4.exec( line ) ) !== null ) {
-
-				// ["f 1//1 2//2 3//3", " 1//1", "1", "1", " 2//2", "2", "2", " 3//3", "3", "3", undefined, undefined, undefined]
-
-				handle_face_line(
-					[ result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ] ], //faces
-					[ ], //uv
-					[ result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ] ] //normal
-				);
-
-			} else if ( /^o /.test( line ) ) {
-
-				// object
-
-				meshN();
-				face_offset = face_offset + vertices.length;
-				vertices = [];
-				object = new THREE.Object3D();
-				object.name = line.substring( 2 ).trim();
-				group.add( object );
-
-			} else if ( /^g /.test( line ) ) {
-
-				// group
-
-				meshN( line.substring( 2 ).trim(), undefined );
-
-			} else if ( /^usemtl /.test( line ) ) {
-
-				// material
-
-				meshN( undefined, line.substring( 7 ).trim() );
-
-			} else if ( /^mtllib /.test( line ) ) {
-
-				// mtl file
-
-				if ( mtllibCallback ) {
-
-					var mtlfile = line.substring( 7 );
-					mtlfile = mtlfile.trim();
-					mtllibCallback( mtlfile );
-
-				}
-
-			} else if ( /^s /.test( line ) ) {
-
-				// Smooth shading
-
-			} else {
-
-				console.log( "THREE.OBJMTLLoader: Unhandled line " + line );
-
-			}
-
-		}
-
-		//Add last object
-		meshN(undefined, undefined);
-
-		return group;
-
-	}
-
-};
-
-THREE.EventDispatcher.apply( THREE.OBJMTLLoader.prototype );
-// END FILE:  OBJMTLLoader.js
-
-// BEGIN FILE:  ColladaLoader2.js
-
-/**
- * @author mrdoob / http://mrdoob.com/
- */
-
-THREE.ColladaLoader = function ( manager ) {
-
-	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
-
-};
-
-THREE.ColladaLoader.prototype = {
-
-	constructor: THREE.ColladaLoader,
-
-	load: function ( url, onLoad, onProgress, onError ) {
-
-		function getBaseUrl( url ) {
-
-			var parts = url.split( '/' );
-			parts.pop();
-			return ( parts.length < 1 ? '.' : parts.join( '/' ) ) + '/';
-
-		}
-
-		var scope = this;
-
-		var loader = new THREE.FileLoader( scope.manager );
-		loader.load( url, function ( text ) {
-
-			onLoad( scope.parse( text, getBaseUrl( url ) ) );
-
-		}, onProgress, onError );
-
-	},
-
-	options: {
-
-		set convertUpAxis ( value ) {
-
-			console.log( 'ColladaLoder.options.convertUpAxis: TODO' );
-
-		}
-
-	},
-
-	setCrossOrigin: function ( value ) {
-
-		this.crossOrigin = value;
-
-	},
-
-	parse: function ( text, baseUrl ) {
-
-		function getElementsByTagName( xml, name ) {
-
-			// Non recursive xml.getElementsByTagName() ...
-
-			var array = [];
-			var childNodes = xml.childNodes;
-
-			for ( var i = 0, l = childNodes.length; i < l; i ++ ) {
-
-				var child = childNodes[ i ];
-
-				if ( child.nodeName === name ) {
-
-					array.push( child );
-
-				}
-
-			}
-
-			return array;
-
-		}
-
-		function parseFloats( text ) {
-
-			if ( text.length === 0 ) return [];
-
-			var parts = text.trim().split( /\s+/ );
-			var array = new Array( parts.length );
-
-			for ( var i = 0, l = parts.length; i < l; i ++ ) {
-
-				array[ i ] = parseFloat( parts[ i ] );
-
-			}
-
-			return array;
-
-		}
-
-		function parseInts( text ) {
-
-			if ( text.length === 0 ) return [];
-
-			var parts = text.trim().split( /\s+/ );
-			var array = new Array( parts.length );
-
-			for ( var i = 0, l = parts.length; i < l; i ++ ) {
-
-				array[ i ] = parseInt( parts[ i ] );
-
-			}
-
-			return array;
-
-		}
-
-		function parseId( text ) {
-
-			return text.substring( 1 );
-
-		}
-
-		// asset
-
-		function parseAsset( xml ) {
-
-			return {
-				unit: parseAssetUnit( getElementsByTagName( xml, 'unit' )[ 0 ] ),
-				upAxis: parseAssetUpAxis( getElementsByTagName( xml, 'up_axis' )[ 0 ] )
-			};
-
-		}
-
-		function parseAssetUnit( xml ) {
-
-			return xml !== undefined ? parseFloat( xml.getAttribute( 'meter' ) ) : 1;
-
-		}
-
-		function parseAssetUpAxis( xml ) {
-
-			return xml !== undefined ? xml.textContent : 'Y_UP';
-
-		}
-
-		// library
-
-		function parseLibrary( xml, data, libraryName, nodeName, parser ) {
-
-			var library = getElementsByTagName( xml, libraryName )[ 0 ];
-
-			if ( library !== undefined ) {
-
-				var elements = getElementsByTagName( library, nodeName );
-
-				for ( var i = 0; i < elements.length; i ++ ) {
-
-					parser( elements[ i ] );
-
-				}
-
-			}
-
-		}
-
-		function buildLibrary( data, builder ) {
-
-			for ( var name in data ) {
-
-				var object = data[ name ];
-				object.build = builder( data[ name ] );
-
-			}
-
-		}
-
-		// get
-
-		function getBuild( data, builder ) {
-
-			if ( data.build !== undefined ) return data.build;
-
-			data.build = builder( data );
-
-			return data.build;
-
-		}
-
-		// image
-
-		var imageLoader = new THREE.ImageLoader();
-
-		function parseImage( xml ) {
-
-			var data = {
-				init_from: getElementsByTagName( xml, 'init_from' )[ 0 ].textContent
-			};
-
-			library.images[ xml.getAttribute( 'id' ) ] = data;
-
-		}
-
-		function buildImage( data ) {
-
-			if ( data.build !== undefined ) return data.build;
-
-			var url = data.init_from;
-
-			if ( baseUrl !== undefined ) url = baseUrl + url;
-
-			return imageLoader.load( url );
-
-		}
-
-		function getImage( id ) {
-
-			return getBuild( library.images[ id ], buildImage );
-
-		}
-
-		// effect
-
-		function parseEffect( xml ) {
-
-			var data = {};
-
-			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				if ( child.nodeType !== 1 ) continue;
-
-				switch ( child.nodeName ) {
-
-					case 'profile_COMMON':
-						data.profile = parseEffectProfileCOMMON( child );
-						break;
-
-				}
-
-			}
-
-			library.effects[ xml.getAttribute( 'id' ) ] = data;
-
-		}
-
-		function parseEffectProfileCOMMON( xml ) {
-
-			var data = {
-				surfaces: {},
-				samplers: {}
-			};
-
-			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				if ( child.nodeType !== 1 ) continue;
-
-				switch ( child.nodeName ) {
-
-					case 'newparam':
-						parseEffectNewparam( child, data );
-						break;
-
-					case 'technique':
-						data.technique = parseEffectTechnique( child );
-						break;
-
-				}
-
-			}
-
-			return data;
-
-		}
-
-		function parseEffectNewparam( xml, data ) {
-
-			var sid = xml.getAttribute( 'sid' );
-
-			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				if ( child.nodeType !== 1 ) continue;
-
-				switch ( child.nodeName ) {
-
-					case 'surface':
-						data.surfaces[ sid ] = parseEffectSurface( child );
-						break;
-
-					case 'sampler2D':
-						data.samplers[ sid ] = parseEffectSampler( child );
-						break;
-
-				}
-
-			}
-
-		}
-
-		function parseEffectSurface( xml ) {
-
-			var data = {};
-
-			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				if ( child.nodeType !== 1 ) continue;
-
-				switch ( child.nodeName ) {
-
-					case 'init_from':
-						data.init_from = child.textContent;
-						break;
-
-				}
-
-			}
-
-			return data;
-
-		}
-
-		function parseEffectSampler( xml ) {
-
-			var data = {};
-
-			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				if ( child.nodeType !== 1 ) continue;
-
-				switch ( child.nodeName ) {
-
-					case 'source':
-						data.source = child.textContent;
-						break;
-
-				}
-
-			}
-
-			return data;
-
-		}
-
-		function parseEffectTechnique( xml ) {
-
-			var data = {};
-
-			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				if ( child.nodeType !== 1 ) continue;
-
-				switch ( child.nodeName ) {
-
-					case 'constant':
-					case 'lambert':
-					case 'blinn':
-					case 'phong':
-						data.type = child.nodeName;
-						data.parameters = parseEffectParameters( child );
-						break;
-
-				}
-
-			}
-
-			return data;
-
-		}
-
-		function parseEffectParameters( xml ) {
-
-			var data = {};
-
-			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				if ( child.nodeType !== 1 ) continue;
-
-				switch ( child.nodeName ) {
-
-					case 'emission':
-					case 'diffuse':
-					case 'specular':
-					case 'shininess':
-					case 'transparency':
-						data[ child.nodeName ] = parseEffectParameter( child );
-						break;
-
-				}
-
-			}
-
-			return data;
-
-		}
-
-		function parseEffectParameter( xml ) {
-
-			var data = {};
-
-			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				if ( child.nodeType !== 1 ) continue;
-
-				switch ( child.nodeName ) {
-
-					case 'color':
-						data[ child.nodeName ] = parseFloats( child.textContent );
-						break;
-
-					case 'float':
-						data[ child.nodeName ] = parseFloat( child.textContent );
-						break;
-
-					case 'texture':
-						data[ child.nodeName ] = child.getAttribute( 'texture' );
-						break;
-
-				}
-
-			}
-
-			return data;
-
-		}
-
-		function buildEffect( data ) {
-
-			return data;
-
-		}
-
-		function getEffect( id ) {
-
-			return getBuild( library.effects[ id ], buildEffect );
-
-		}
-
-		// material
-
-		function parseMaterial( xml ) {
-
-			var data = {
-				name: xml.getAttribute( 'name' )
-			};
-
-			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				if ( child.nodeType !== 1 ) continue;
-
-				switch ( child.nodeName ) {
-
-					case 'instance_effect':
-						data.url = parseId( child.getAttribute( 'url' ) );
-						break;
-
-				}
-
-			}
-
-			library.materials[ xml.getAttribute( 'id' ) ] = data;
-
-		}
-
-		function buildMaterial( data ) {
-
-			var effect = getEffect( data.url );
-			var technique = effect.profile.technique;
-
-			var material;
-
-			switch ( technique.type ) {
-
-				case 'phong':
-				case 'blinn':
-					material = new THREE.MeshPhongMaterial();
-					break;
-
-				case 'lambert':
-					material = new THREE.MeshLambertMaterial();
-					break;
-
-				default:
-					material = new THREE.MeshBasicMaterial();
-					break;
-
-			}
-
-			material.name = data.name;
-
-			function getTexture( sid ) {
-
-				var sampler = effect.profile.samplers[ sid ];
-
-				if ( sampler !== undefined ) {
-
-					var surface = effect.profile.surfaces[ sampler.source ];
-
-					var texture = new THREE.Texture( getImage( surface.init_from ) );
-					texture.wrapS = THREE.RepeatWrapping;
-					texture.wrapT = THREE.RepeatWrapping;
-					texture.needsUpdate = true;
-
-					return texture;
-
-				}
-
-				console.error( 'ColladaLoder: Undefined sampler', sid );
-
-				return null;
-
-			}
-
-			var parameters = technique.parameters;
-
-			for ( var key in parameters ) {
-
-				var parameter = parameters[ key ];
-
-				switch ( key ) {
-					case 'diffuse':
-						if ( parameter.color ) material.color.fromArray( parameter.color );
-						if ( parameter.texture ) material.map = getTexture( parameter.texture );
-						break;
-					case 'specular':
-						if ( parameter.color && material.specular )
-							material.specular.fromArray( parameter.color );
-						break;
-					case 'shininess':
-						if ( parameter.float && material.shininess )
-							material.shininess = parameter.float;
-						break;
-					case 'emission':
-						if ( parameter.color && material.emissive )
-							material.emissive.fromArray( parameter.color );
-						break;
-					case 'transparency':
-						if ( parameter.float )
-							material.opacity = parameter.float;
-						if ( parameter.float !== 1 )
-							material.transparent = true;
-						break;
-				}
-
-			}
-
-			return material;
-
-		}
-
-		function getMaterial( id ) {
-
-			return getBuild( library.materials[ id ], buildMaterial );
-
-		}
-
-		// camera
-
-		function parseCamera( xml ) {
-
-			var data = {
-				name: xml.getAttribute( 'name' )
-			};
-
-			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				if ( child.nodeType !== 1 ) continue;
-
-				switch ( child.nodeName ) {
-
-					case 'optics':
-						data.optics = parseCameraOptics( child );
-						break;
-
-				}
-
-			}
-
-			library.cameras[ xml.getAttribute( 'id' ) ] = data;
-
-		}
-
-		function parseCameraOptics( xml ) {
-
-			for ( var i = 0; i < xml.childNodes.length; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				switch ( child.nodeName ) {
-
-					case 'technique_common':
-						return parseCameraTechnique( child );
-
-				}
-
-			}
-
-			return {};
-
-		}
-
-		function parseCameraTechnique( xml ) {
-
-			var data = {};
-
-			for ( var i = 0; i < xml.childNodes.length; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				switch ( child.nodeName ) {
-
-					case 'perspective':
-					case 'orthographic':
-
-						data.technique = child.nodeName;
-						data.parameters = parseCameraParameters( child );
-
-						break;
-
-				}
-
-			}
-
-			return data;
-
-		}
-
-		function parseCameraParameters( xml ) {
-
-			var data = {};
-
-			for ( var i = 0; i < xml.childNodes.length; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				switch ( child.nodeName ) {
-
-					case 'xfov':
-					case 'yfov':
-					case 'xmag':
-					case 'ymag':
-					case 'znear':
-					case 'zfar':
-					case 'aspect_ratio':
-						data[ child.nodeName ] = parseFloat( child.textContent );
-						break;
-
-				}
-
-			}
-
-			return data;
-
-		}
-
-		function buildCamera( data ) {
-
-			var camera;
-
-			switch ( data.optics.technique ) {
-
-				case 'perspective':
-					camera = new THREE.PerspectiveCamera(
-						data.optics.parameters.yfov,
-						data.optics.parameters.aspect_ratio,
-						data.optics.parameters.znear,
-						data.optics.parameters.zfar
-					);
-					break;
-
-				case 'orthographic':
-					camera = new THREE.OrthographicCamera( /* TODO */ );
-					break;
-
-				default:
-					camera = new THREE.PerspectiveCamera();
-					break;
-
-			}
-
-			camera.name = data.name;
-
-			return camera;
-
-		}
-
-		function getCamera( id ) {
-
-			return getBuild( library.cameras[ id ], buildCamera );
-
-		}
-
-		// light
-
-		function parseLight( xml ) {
-
-			var data = {};
-
-			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				if ( child.nodeType !== 1 ) continue;
-
-				switch ( child.nodeName ) {
-
-					case 'technique_common':
-						data = parseLightTechnique( child );
-						break;
-
-				}
-
-			}
-
-			library.lights[ xml.getAttribute( 'id' ) ] = data;
-
-		}
-
-		function parseLightTechnique( xml ) {
-
-			var data = {};
-
-			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				if ( child.nodeType !== 1 ) continue;
-
-				switch ( child.nodeName ) {
-
-					case 'directional':
-					case 'point':
-					case 'spot':
-					case 'ambient':
-
-						data.technique = child.nodeName;
-						data.parameters = parseLightParameters( child );
-
-				}
-
-			}
-
-			return data;
-
-		}
-
-		function parseLightParameters( xml ) {
-
-			var data = {};
-
-			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				if ( child.nodeType !== 1 ) continue;
-
-				switch ( child.nodeName ) {
-
-					case 'color':
-						var array = parseFloats( child.textContent );
-						data.color = new THREE.Color().fromArray( array );
-						break;
-
-					case 'falloff_angle':
-						data.falloffAngle = parseFloat( child.textContent );
-						break;
-
-					case 'quadratic_attenuation':
-						var f = parseFloat( child.textContent );
-						data.distance = f ? Math.sqrt( 1 / f ) : 0;
-						break;
-
-				}
-
-			}
-
-			return data;
-
-		}
-
-		function buildLight( data ) {
-
-			var light;
-
-			switch ( data.technique ) {
-
-				case 'directional':
-					light = new THREE.DirectionalLight();
-					break;
-
-				case 'point':
-					light = new THREE.PointLight();
-					break;
-
-				case 'spot':
-					light = new THREE.SpotLight();
-					break;
-
-				case 'ambient':
-					light = new THREE.AmbientLight();
-					break;
-
-			}
-
-			if ( data.parameters.color ) light.color.copy( data.parameters.color );
-			if ( data.parameters.distance ) light.distance = data.parameters.distance;
-
-			return light;
-
-		}
-
-		function getLight( id ) {
-
-			return getBuild( library.lights[ id ], buildLight );
-
-		}
-
-		// geometry
-
-		function parseGeometry( xml ) {
-
-			var data = {
-				name: xml.getAttribute( 'name' ),
-				sources: {},
-				vertices: {},
-				primitives: []
-			};
-
-			var mesh = getElementsByTagName( xml, 'mesh' )[ 0 ];
-
-			for ( var i = 0; i < mesh.childNodes.length; i ++ ) {
-
-				var child = mesh.childNodes[ i ];
-
-				if ( child.nodeType !== 1 ) continue;
-
-				var id = child.getAttribute( 'id' );
-
-				switch ( child.nodeName ) {
-
-					case 'source':
-						data.sources[ id ] = parseGeometrySource( child );
-						break;
-
-					case 'vertices':
-						// data.sources[ id ] = data.sources[ parseId( getElementsByTagName( child, 'input' )[ 0 ].getAttribute( 'source' ) ) ];
-						data.vertices = parseGeometryVertices( child );
-						break;
-
-					case 'polygons':
-						console.log( 'ColladaLoader: Unsupported primitive type: ', child.nodeName );
-						break;
-
-					case 'lines':
-					case 'linestrips':
-					case 'polylist':
-					case 'triangles':
-						data.primitives.push( parseGeometryPrimitive( child ) );
-						break;
-
-					default:
-						console.log( child );
-
-				}
-
-			}
-
-			library.geometries[ xml.getAttribute( 'id' ) ] = data;
-
-		}
-
-		function parseGeometrySource( xml ) {
-
-			var data = {
-				array: [],
-				stride: 3
-			};
-
-			for ( var i = 0; i < xml.childNodes.length; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				if ( child.nodeType !== 1 ) continue;
-
-				switch ( child.nodeName ) {
-
-					case 'float_array':
-						data.array = parseFloats( child.textContent );
-						break;
-
-					case 'technique_common':
-						var accessor = getElementsByTagName( child, 'accessor' )[ 0 ];
-
-						if ( accessor !== undefined ) {
-
-							data.stride = parseInt( accessor.getAttribute( 'stride' ) );
-
-						}
-						break;
-
-					default:
-						console.log( child );
-
-				}
-
-			}
-
-			return data;
-
-		}
-
-		function parseGeometryVertices( xml ) {
-
-			var data = {};
-
-			for ( var i = 0; i < xml.childNodes.length; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				if ( child.nodeType !== 1 ) continue;
-
-				data[ child.getAttribute( 'semantic' ) ] = parseId( child.getAttribute( 'source' ) );
-
-			}
-
-			return data;
-
-		}
-
-		function parseGeometryPrimitive( xml ) {
-
-			var primitive = {
-				type: xml.nodeName,
-				material: xml.getAttribute( 'material' ),
-				inputs: {},
-				stride: 0
-			};
-
-			for ( var i = 0, l = xml.childNodes.length; i < l; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				if ( child.nodeType !== 1 ) continue;
-
-				switch ( child.nodeName ) {
-
-					case 'input':
-						var id = parseId( child.getAttribute( 'source' ) );
-						var semantic = child.getAttribute( 'semantic' );
-						var offset = parseInt( child.getAttribute( 'offset' ) );
-						primitive.inputs[ semantic ] = { id: id, offset: offset };
-						primitive.stride = Math.max( primitive.stride, offset + 1 );
-						break;
-
-					case 'vcount':
-						primitive.vcount = parseInts( child.textContent );
-						break;
-
-					case 'p':
-						primitive.p = parseInts( child.textContent );
-						break;
-
-				}
-
-			}
-
-			return primitive;
-
-		}
-
-		var DEFAULT_LINEMATERIAL = new THREE.LineBasicMaterial();
-		var DEFAULT_MESHMATERIAL = new THREE.MeshPhongMaterial();
-
-		function buildGeometry( data ) {
-
-			var group = {};
-
-			var sources = data.sources;
-			var vertices = data.vertices;
-			var primitives = data.primitives;
-
-			if ( primitives.length === 0 ) return group;
-
-			for ( var p = 0; p < primitives.length; p ++ ) {
-
-				var primitive = primitives[ p ];
-				var inputs = primitive.inputs;
-
-				var geometry = new THREE.BufferGeometry();
-
-				if ( data.name ) geometry.name = data.name;
-
-				for ( var name in inputs ) {
-
-					var input = inputs[ name ];
-
-					switch ( name )	{
-
-						case 'VERTEX':
-							for ( var key in vertices ) {
-
-								geometry.addAttribute( key.toLowerCase(), buildGeometryAttribute( primitive, sources[ vertices[ key ] ], input.offset ) );
-
-							}
-							break;
-
-						case 'NORMAL':
-							geometry.addAttribute( 'normal', buildGeometryAttribute( primitive, sources[ input.id ], input.offset ) );
-							break;
-
-						case 'COLOR':
-							geometry.addAttribute( 'color', buildGeometryAttribute( primitive, sources[ input.id ], input.offset ) );
-							break;
-
-						case 'TEXCOORD':
-							geometry.addAttribute( 'uv', buildGeometryAttribute( primitive, sources[ input.id ], input.offset ) );
-							break;
-
-					}
-
-				}
-
-				var object;
-
-				switch ( primitive.type ) {
-
-					case 'lines':
-						object = new THREE.LineSegments( geometry, DEFAULT_LINEMATERIAL );
-						break;
-
-					case 'linestrips':
-						object = new THREE.Line( geometry, DEFAULT_LINEMATERIAL );
-						break;
-
-					case 'triangles':
-					case 'polylist':
-						object = new THREE.Mesh( geometry, DEFAULT_MESHMATERIAL );
-						break;
-
-				}
-
-				group[ primitive.material ] = object;
-
-			}
-
-			return group;
-
-		}
-
-		function buildGeometryAttribute( primitive, source, offset ) {
-
-			var indices = primitive.p;
-			var stride = primitive.stride;
-			var vcount = primitive.vcount;
-
-			function pushVector( i ) {
-
-				var index = indices[ i + offset ] * sourceStride;
-				var length = index + sourceStride;
-
-				for ( ; index < length; index ++ ) {
-
-					array.push( sourceArray[ index ] );
-
-				}
-
-			}
-
-			var maxcount = 0;
-
-			var sourceArray = source.array;
-			var sourceStride = source.stride;
-
-			var array = [];
-
-			if ( primitive.vcount !== undefined ) {
-
-				var index = 0;
-
-				for ( var i = 0, l = vcount.length; i < l; i ++ ) {
-
-					var count = vcount[ i ];
-
-					if ( count === 4 ) {
-
-						var a = index + stride * 0;
-						var b = index + stride * 1;
-						var c = index + stride * 2;
-						var d = index + stride * 3;
-
-						pushVector( a ); pushVector( b ); pushVector( d );
-						pushVector( b ); pushVector( c ); pushVector( d );
-
-					} else if ( count === 3 ) {
-
-						var a = index + stride * 0;
-						var b = index + stride * 1;
-						var c = index + stride * 2;
-
-						pushVector( a ); pushVector( b ); pushVector( c );
-
-					} else {
-
-						maxcount = Math.max( maxcount, count );
-
-					}
-
-					index += stride * count;
-
-				}
-
-				if ( maxcount > 0 ) {
-
-					console.log( 'ColladaLoader: Geometry has faces with more than 4 vertices.' );
-
-				}
-
-			} else {
-
-				for ( var i = 0, l = indices.length; i < l; i += stride ) {
-
-					pushVector( i );
-
-				}
-
-			}
-
-			return new THREE.Float32Attribute( array, sourceStride );
-
-		}
-
-		function getGeometry( id ) {
-
-			return getBuild( library.geometries[ id ], buildGeometry );
-
-		}
-
-		// nodes
-
-		var matrix = new THREE.Matrix4();
-		var vector = new THREE.Vector3();
-
-		function parseNode( xml ) {
-
-			var data = {
-				name: xml.getAttribute( 'name' ),
-				matrix: new THREE.Matrix4(),
-				nodes: [],
-				instanceCameras: [],
-				instanceLights: [],
-				instanceGeometries: [],
-				instanceNodes: []
-			};
-
-			for ( var i = 0; i < xml.childNodes.length; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				if ( child.nodeType !== 1 ) continue;
-
-				switch ( child.nodeName ) {
-
-					case 'node':
-						parseNode( child );
-						data.nodes.push( child.getAttribute( 'id' ) );
-						break;
-
-					case 'instance_camera':
-						data.instanceCameras.push( parseId( child.getAttribute( 'url' ) ) );
-						break;
-
-					case 'instance_light':
-						data.instanceLights.push( parseId( child.getAttribute( 'url' ) ) );
-						break;
-
-					case 'instance_geometry':
-						data.instanceGeometries.push( parseNodeInstanceGeometry( child ) );
-						break;
-
-					case 'instance_node':
-						data.instanceNodes.push( parseId( child.getAttribute( 'url' ) ) );
-						break;
-
-					case 'matrix':
-						var array = parseFloats( child.textContent );
-						data.matrix.multiply( matrix.fromArray( array ).transpose() ); // .transpose() when Z_UP?
-						break;
-
-					case 'translate':
-						var array = parseFloats( child.textContent );
-						vector.fromArray( array );
-						data.matrix.multiply( matrix.makeTranslation( vector.x, vector.y, vector.z ) );
-						break;
-
-					case 'rotate':
-						var array = parseFloats( child.textContent );
-						var angle = THREE.Math.degToRad( array[ 3 ] );
-						data.matrix.multiply( matrix.makeRotationAxis( vector.fromArray( array ), angle ) );
-						break;
-
-					case 'scale':
-						var array = parseFloats( child.textContent );
-						data.matrix.scale( vector.fromArray( array ) );
-						break;
-
-					case 'extra':
-						break;
-
-					default:
-						console.log( child );
-
-				}
-
-			}
-
-			if ( xml.getAttribute( 'id' ) !== null ) {
-
-				library.nodes[ xml.getAttribute( 'id' ) ] = data;
-
-			}
-
-			return data;
-
-		}
-
-		function parseNodeInstanceGeometry( xml ) {
-
-			var data = {
-				id: parseId( xml.getAttribute( 'url' ) ),
-				materials: {}
-			};
-
-			for ( var i = 0; i < xml.childNodes.length; i ++ ) {
-
-				var child = xml.childNodes[ i ];
-
-				if ( child.nodeName === 'bind_material' ) {
-
-					var instances = child.getElementsByTagName( 'instance_material' );
-
-					for ( var j = 0; j < instances.length; j ++ ) {
-
-						var instance = instances[ j ];
-						var symbol = instance.getAttribute( 'symbol' );
-						var target = instance.getAttribute( 'target' );
-
-						data.materials[ symbol ] = parseId( target );
-
-					}
-
-					break;
-
-				}
-
-			}
-
-			return data;
-
-		}
-
-		function buildNode( data ) {
-
-			var objects = [];
-
-			var matrix = data.matrix;
-			var nodes = data.nodes;
-			var instanceCameras = data.instanceCameras;
-			var instanceLights = data.instanceLights;
-			var instanceGeometries = data.instanceGeometries;
-			var instanceNodes = data.instanceNodes;
-
-			for ( var i = 0, l = nodes.length; i < l; i ++ ) {
-
-				objects.push( getNode( nodes[ i ] ).clone() );
-
-			}
-
-			for ( var i = 0, l = instanceCameras.length; i < l; i ++ ) {
-
-				objects.push( getCamera( instanceCameras[ i ] ).clone() );
-
-			}
-
-			for ( var i = 0, l = instanceLights.length; i < l; i ++ ) {
-
-				objects.push( getLight( instanceLights[ i ] ).clone() );
-
-			}
-
-			for ( var i = 0, l = instanceGeometries.length; i < l; i ++ ) {
-
-				var instance = instanceGeometries[ i ];
-				var geometries = getGeometry( instance.id );
-
-				for ( var key in geometries ) {
-
-					var object = geometries[ key ].clone();
-
-					if ( instance.materials[ key ] !== undefined ) {
-
-						object.material = getMaterial( instance.materials[ key ] );
-
-					}
-
-					objects.push( object );
-
-				}
-
-			}
-
-			for ( var i = 0, l = instanceNodes.length; i < l; i ++ ) {
-
-				objects.push( getNode( instanceNodes[ i ] ).clone() );
-
-			}
-
-			var object;
-
-			if ( nodes.length === 0 && objects.length === 1 ) {
-
-				object = objects[ 0 ];
-
-			} else {
-
-				object = new THREE.Group();
-
-				for ( var i = 0; i < objects.length; i ++ ) {
-
-					object.add( objects[ i ] );
-
-				}
-
-			}
-
-			object.name = data.name;
-			matrix.decompose( object.position, object.quaternion, object.scale );
-
-			return object;
-
-		}
-
-		function getNode( id ) {
-
-			return getBuild( library.nodes[ id ], buildNode );
-
-		}
-
-		// visual scenes
-
-		function parseVisualScene( xml ) {
-
-			var data = {
-				name: xml.getAttribute( 'name' ),
-				children: []
-			};
-
-			var elements = getElementsByTagName( xml, 'node' );
-
-			for ( var i = 0; i < elements.length; i ++ ) {
-
-				data.children.push( parseNode( elements[ i ] ) );
-
-			}
-
-			library.visualScenes[ xml.getAttribute( 'id' ) ] = data;
-
-		}
-
-		function buildVisualScene( data ) {
-
-			var group = new THREE.Group();
-			group.name = data.name;
-
-			var children = data.children;
-
-			for ( var i = 0; i < children.length; i ++ ) {
-
-				group.add( buildNode( children[ i ] ) );
-
-			}
-
-			return group;
-
-		}
-
-		function getVisualScene( id ) {
-
-			return getBuild( library.visualScenes[ id ], buildVisualScene );
-
-		}
-
-		// scenes
-
-		function parseScene( xml ) {
-
-			var instance = getElementsByTagName( xml, 'instance_visual_scene' )[ 0 ];
-			return getVisualScene( parseId( instance.getAttribute( 'url' ) ) );
-
-		}
-
-		console.time( 'ColladaLoader' );
-
-		if ( text.length === 0 ) {
-
-			return { scene: new THREE.Scene() };
-
-		}
-
-		console.time( 'ColladaLoader: DOMParser' );
-
-		var xml = new DOMParser().parseFromString( text, 'application/xml' );
-
-		console.timeEnd( 'ColladaLoader: DOMParser' );
-
-		var collada = getElementsByTagName( xml, 'COLLADA' )[ 0 ];
-
-		// metadata
-
-		var version = collada.getAttribute( 'version' );
-		console.log( 'ColladaLoader: File version', version );
-
-		var asset = parseAsset( getElementsByTagName( collada, 'asset' )[ 0 ] );
-
-		//
-
-		var library = {
-			images: {},
-			effects: {},
-			materials: {},
-			cameras: {},
-			lights: {},
-			geometries: {},
-			nodes: {},
-			visualScenes: {}
-		};
-
-		console.time( 'ColladaLoader: Parse' );
-
-		parseLibrary( collada, library.images, 'library_images', 'image', parseImage );
-		parseLibrary( collada, library.effects, 'library_effects', 'effect', parseEffect );
-		parseLibrary( collada, library.materials, 'library_materials', 'material', parseMaterial );
-		parseLibrary( collada, library.cameras, 'library_cameras', 'camera', parseCamera );
-		parseLibrary( collada, library.lights, 'library_lights', 'light', parseLight );
-		parseLibrary( collada, library.geometries, 'library_geometries', 'geometry', parseGeometry );
-		parseLibrary( collada, library.nodes, 'library_nodes', 'node', parseNode );
-		parseLibrary( collada, library.visualScenes, 'library_visual_scenes', 'visual_scene', parseVisualScene );
-
-		console.timeEnd( 'ColladaLoader: Parse' );
-
-		console.time( 'ColladaLoader: Build' );
-
-		buildLibrary( library.images, buildImage );
-		buildLibrary( library.effects, buildEffect );
-		buildLibrary( library.materials, buildMaterial );
-		buildLibrary( library.cameras, buildCamera );
-		buildLibrary( library.lights, buildLight );
-		buildLibrary( library.geometries, buildGeometry );
-		buildLibrary( library.nodes, buildNode );
-		buildLibrary( library.visualScenes, buildVisualScene );
-
-		console.timeEnd( 'ColladaLoader: Build' );
-
-		// console.log( library );
-
-		var scene = parseScene( getElementsByTagName( collada, 'scene' )[ 0 ] );
-
-		if ( asset.upAxis === 'Z_UP' ) {
-
-			scene.rotation.x = - Math.PI / 2;
-
-		}
-
-		scene.scale.multiplyScalar( asset.unit );
-
-		console.timeEnd( 'ColladaLoader' );
-
-		// console.log( scene );
-
-		return {
-			animations: [],
-			kinematics: { joints: [] },
-			scene: scene
-		};
-
-	}
-
-};
-
-
-// END FILE:  ColladaLoader.js
-
-// BEGIN FILE:  Projector.js
-/**
- * @author mrdoob / http://mrdoob.com/
- * @author supereggbert / http://www.paulbrunt.co.uk/
- * @author julianwa / https://github.com/julianwa
- */
-
-THREE.RenderableObject = function () {
-
-	this.id = 0;
-
-	this.object = null;
-	this.z = 0;
-	this.renderOrder = 0;
-
-};
-
-//
-
-THREE.RenderableFace = function () {
-
-	this.id = 0;
-
-	this.v1 = new THREE.RenderableVertex();
-	this.v2 = new THREE.RenderableVertex();
-	this.v3 = new THREE.RenderableVertex();
-
-	this.normalModel = new THREE.Vector3();
-
-	this.vertexNormalsModel = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
-	this.vertexNormalsLength = 0;
-
-	this.color = new THREE.Color();
-	this.material = null;
-	this.uvs = [ new THREE.Vector2(), new THREE.Vector2(), new THREE.Vector2() ];
-
-	this.z = 0;
-	this.renderOrder = 0;
-
-};
-
-//
-
-THREE.RenderableVertex = function () {
-
-	this.position = new THREE.Vector3();
-	this.positionWorld = new THREE.Vector3();
-	this.positionScreen = new THREE.Vector4();
-
-	this.visible = true;
-
-};
-
-THREE.RenderableVertex.prototype.copy = function ( vertex ) {
-
-	this.positionWorld.copy( vertex.positionWorld );
-	this.positionScreen.copy( vertex.positionScreen );
-
-};
-
-//
-
-THREE.RenderableLine = function () {
-
-	this.id = 0;
-
-	this.v1 = new THREE.RenderableVertex();
-	this.v2 = new THREE.RenderableVertex();
-
-	this.vertexColors = [ new THREE.Color(), new THREE.Color() ];
-	this.material = null;
-
-	this.z = 0;
-	this.renderOrder = 0;
-
-};
-
-//
-
-THREE.RenderableSprite = function () {
-
-	this.id = 0;
-
-	this.object = null;
-
-	this.x = 0;
-	this.y = 0;
-	this.z = 0;
-
-	this.rotation = 0;
-	this.scale = new THREE.Vector2();
-
-	this.material = null;
-	this.renderOrder = 0;
-
-};
-
-//
-
-THREE.Projector = function () {
-
-	var _object, _objectCount, _objectPool = [], _objectPoolLength = 0,
-	_vertex, _vertexCount, _vertexPool = [], _vertexPoolLength = 0,
-	_face, _faceCount, _facePool = [], _facePoolLength = 0,
-	_line, _lineCount, _linePool = [], _linePoolLength = 0,
-	_sprite, _spriteCount, _spritePool = [], _spritePoolLength = 0,
-
-	_renderData = { objects: [], lights: [], elements: [] },
-
-	_vector3 = new THREE.Vector3(),
-	_vector4 = new THREE.Vector4(),
-
-	_clipBox = new THREE.Box3( new THREE.Vector3( - 1, - 1, - 1 ), new THREE.Vector3( 1, 1, 1 ) ),
-	_boundingBox = new THREE.Box3(),
-	_points3 = new Array( 3 ),
-	_points4 = new Array( 4 ),
-
-	_viewMatrix = new THREE.Matrix4(),
-	_viewProjectionMatrix = new THREE.Matrix4(),
-
-	_modelMatrix,
-	_modelViewProjectionMatrix = new THREE.Matrix4(),
-
-	_normalMatrix = new THREE.Matrix3(),
-
-	_frustum = new THREE.Frustum(),
-
-	_clippedVertex1PositionScreen = new THREE.Vector4(),
-	_clippedVertex2PositionScreen = new THREE.Vector4();
-
-	//
-
-	this.projectVector = function ( vector, camera ) {
-
-		console.warn( 'THREE.Projector: .projectVector() is now vector.project().' );
-		vector.project( camera );
-
-	};
-
-	this.unprojectVector = function ( vector, camera ) {
-
-		console.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' );
-		vector.unproject( camera );
-
-	};
-
-	this.pickingRay = function ( vector, camera ) {
-
-		console.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' );
-
-	};
-
-	//
-
-	var RenderList = function () {
-
-		var normals = [];
-		var uvs = [];
-
-		var object = null;
-		var material = null;
-
-		var normalMatrix = new THREE.Matrix3();
-
-		function setObject( value ) {
-
-			object = value;
-			material = object.material;
-
-			normalMatrix.getNormalMatrix( object.matrixWorld );
-
-			normals.length = 0;
-			uvs.length = 0;
-
-		}
-
-		function projectVertex( vertex ) {
-
-			var position = vertex.position;
-			var positionWorld = vertex.positionWorld;
-			var positionScreen = vertex.positionScreen;
-
-			positionWorld.copy( position ).applyMatrix4( _modelMatrix );
-			positionScreen.copy( positionWorld ).applyMatrix4( _viewProjectionMatrix );
-
-			var invW = 1 / positionScreen.w;
-
-			positionScreen.x *= invW;
-			positionScreen.y *= invW;
-			positionScreen.z *= invW;
-
-			vertex.visible = positionScreen.x >= - 1 && positionScreen.x <= 1 &&
-					 positionScreen.y >= - 1 && positionScreen.y <= 1 &&
-					 positionScreen.z >= - 1 && positionScreen.z <= 1;
-
-		}
-
-		function pushVertex( x, y, z ) {
-
-			_vertex = getNextVertexInPool();
-			_vertex.position.set( x, y, z );
-
-			projectVertex( _vertex );
-
-		}
-
-		function pushNormal( x, y, z ) {
-
-			normals.push( x, y, z );
-
-		}
-
-		function pushUv( x, y ) {
-
-			uvs.push( x, y );
-
-		}
-
-		function checkTriangleVisibility( v1, v2, v3 ) {
-
-			if ( v1.visible === true || v2.visible === true || v3.visible === true ) return true;
-
-			_points3[ 0 ] = v1.positionScreen;
-			_points3[ 1 ] = v2.positionScreen;
-			_points3[ 2 ] = v3.positionScreen;
-
-			return _clipBox.intersectsBox( _boundingBox.setFromPoints( _points3 ) );
-
-		}
-
-		function checkBackfaceCulling( v1, v2, v3 ) {
-
-			return ( ( v3.positionScreen.x - v1.positionScreen.x ) *
-				    ( v2.positionScreen.y - v1.positionScreen.y ) -
-				    ( v3.positionScreen.y - v1.positionScreen.y ) *
-				    ( v2.positionScreen.x - v1.positionScreen.x ) ) < 0;
-
-		}
-
-		function pushLine( a, b ) {
-
-			var v1 = _vertexPool[ a ];
-			var v2 = _vertexPool[ b ];
-
-			_line = getNextLineInPool();
-
-			_line.id = object.id;
-			_line.v1.copy( v1 );
-			_line.v2.copy( v2 );
-			_line.z = ( v1.positionScreen.z + v2.positionScreen.z ) / 2;
-			_line.renderOrder = object.renderOrder;
-
-			_line.material = object.material;
-
-			_renderData.elements.push( _line );
-
-		}
-
-		function pushTriangle( a, b, c ) {
-
-			var v1 = _vertexPool[ a ];
-			var v2 = _vertexPool[ b ];
-			var v3 = _vertexPool[ c ];
-
-			if ( checkTriangleVisibility( v1, v2, v3 ) === false ) return;
-
-			if ( material.side === THREE.DoubleSide || checkBackfaceCulling( v1, v2, v3 ) === true ) {
-
-				_face = getNextFaceInPool();
-
-				_face.id = object.id;
-				_face.v1.copy( v1 );
-				_face.v2.copy( v2 );
-				_face.v3.copy( v3 );
-				_face.z = ( v1.positionScreen.z + v2.positionScreen.z + v3.positionScreen.z ) / 3;
-				_face.renderOrder = object.renderOrder;
-
-				// use first vertex normal as face normal
-
-				_face.normalModel.fromArray( normals, a * 3 );
-				_face.normalModel.applyMatrix3( normalMatrix ).normalize();
-
-				for ( var i = 0; i < 3; i ++ ) {
-
-					var normal = _face.vertexNormalsModel[ i ];
-					normal.fromArray( normals, arguments[ i ] * 3 );
-					normal.applyMatrix3( normalMatrix ).normalize();
-
-					var uv = _face.uvs[ i ];
-					uv.fromArray( uvs, arguments[ i ] * 2 );
-
-				}
-
-				_face.vertexNormalsLength = 3;
-
-				_face.material = object.material;
-
-				_renderData.elements.push( _face );
-
-			}
-
-		}
-
-		return {
-			setObject: setObject,
-			projectVertex: projectVertex,
-			checkTriangleVisibility: checkTriangleVisibility,
-			checkBackfaceCulling: checkBackfaceCulling,
-			pushVertex: pushVertex,
-			pushNormal: pushNormal,
-			pushUv: pushUv,
-			pushLine: pushLine,
-			pushTriangle: pushTriangle
-		}
-
-	};
-
-	var renderList = new RenderList();
-
-	this.projectScene = function ( scene, camera, sortObjects, sortElements ) {
-
-		_faceCount = 0;
-		_lineCount = 0;
-		_spriteCount = 0;
-
-		_renderData.elements.length = 0;
-
-		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
-		if ( camera.parent === null ) camera.updateMatrixWorld();
-
-		_viewMatrix.copy( camera.matrixWorldInverse.getInverse( camera.matrixWorld ) );
-		_viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, _viewMatrix );
-
-		_frustum.setFromMatrix( _viewProjectionMatrix );
-
-		//
-
-		_objectCount = 0;
-
-		_renderData.objects.length = 0;
-		_renderData.lights.length = 0;
-
-		scene.traverseVisible( function ( object ) {
-
-			if ( object instanceof THREE.Light ) {
-
-				_renderData.lights.push( object );
-
-			} else if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.Sprite ) {
-
-				var material = object.material;
-
-				if ( material.visible === false ) return;
-
-				if ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) {
-
-					_object = getNextObjectInPool();
-					_object.id = object.id;
-					_object.object = object;
-
-					_vector3.setFromMatrixPosition( object.matrixWorld );
-					_vector3.applyProjection( _viewProjectionMatrix );
-					_object.z = _vector3.z;
-					_object.renderOrder = object.renderOrder;
-
-					_renderData.objects.push( _object );
-
-				}
-
-			}
-
-		} );
-
-		if ( sortObjects === true ) {
-
-			_renderData.objects.sort( painterSort );
-
-		}
-
-		//
-
-		for ( var o = 0, ol = _renderData.objects.length; o < ol; o ++ ) {
-
-			var object = _renderData.objects[ o ].object;
-			var geometry = object.geometry;
-
-			renderList.setObject( object );
-
-			_modelMatrix = object.matrixWorld;
-
-			_vertexCount = 0;
-
-			if ( object instanceof THREE.Mesh ) {
-
-				if ( geometry instanceof THREE.BufferGeometry ) {
-
-					var attributes = geometry.attributes;
-					var groups = geometry.groups;
-
-					if ( attributes.position === undefined ) continue;
-
-					var positions = attributes.position.array;
-
-					for ( var i = 0, l = positions.length; i < l; i += 3 ) {
-
-						renderList.pushVertex( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
-
-					}
-
-					if ( attributes.normal !== undefined ) {
-
-						var normals = attributes.normal.array;
-
-						for ( var i = 0, l = normals.length; i < l; i += 3 ) {
-
-							renderList.pushNormal( normals[ i ], normals[ i + 1 ], normals[ i + 2 ] );
-
-						}
-
-					}
-
-					if ( attributes.uv !== undefined ) {
-
-						var uvs = attributes.uv.array;
-
-						for ( var i = 0, l = uvs.length; i < l; i += 2 ) {
-
-							renderList.pushUv( uvs[ i ], uvs[ i + 1 ] );
-
-						}
-
-					}
-
-					if ( geometry.index !== null ) {
-
-						var indices = geometry.index.array;
-
-						if ( groups.length > 0 ) {
-
-							for ( var o = 0; o < groups.length; o ++ ) {
-
-								var group = groups[ o ];
-
-								for ( var i = group.start, l = group.start + group.count; i < l; i += 3 ) {
-
-									renderList.pushTriangle( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );
-
-								}
-
-							}
-
-						} else {
-
-							for ( var i = 0, l = indices.length; i < l; i += 3 ) {
-
-								renderList.pushTriangle( indices[ i ], indices[ i + 1 ], indices[ i + 2 ] );
-
-							}
-
-						}
-
-					} else {
-
-						for ( var i = 0, l = positions.length / 3; i < l; i += 3 ) {
-
-							renderList.pushTriangle( i, i + 1, i + 2 );
-
-						}
-
-					}
-
-				} else if ( geometry instanceof THREE.Geometry ) {
-
-					var vertices = geometry.vertices;
-					var faces = geometry.faces;
-					var faceVertexUvs = geometry.faceVertexUvs[ 0 ];
-
-					_normalMatrix.getNormalMatrix( _modelMatrix );
-
-					var material = object.material;
-
-					var isFaceMaterial = material instanceof THREE.MultiMaterial;
-					var objectMaterials = isFaceMaterial === true ? object.material : null;
-
-					for ( var v = 0, vl = vertices.length; v < vl; v ++ ) {
-
-						var vertex = vertices[ v ];
-
-						_vector3.copy( vertex );
-
-						if ( material.morphTargets === true ) {
-
-							var morphTargets = geometry.morphTargets;
-							var morphInfluences = object.morphTargetInfluences;
-
-							for ( var t = 0, tl = morphTargets.length; t < tl; t ++ ) {
-
-								var influence = morphInfluences[ t ];
-
-								if ( influence === 0 ) continue;
-
-								var target = morphTargets[ t ];
-								var targetVertex = target.vertices[ v ];
-
-								_vector3.x += ( targetVertex.x - vertex.x ) * influence;
-								_vector3.y += ( targetVertex.y - vertex.y ) * influence;
-								_vector3.z += ( targetVertex.z - vertex.z ) * influence;
-
-							}
-
-						}
-
-						renderList.pushVertex( _vector3.x, _vector3.y, _vector3.z );
-
-					}
-
-					for ( var f = 0, fl = faces.length; f < fl; f ++ ) {
-
-						var face = faces[ f ];
-
-						material = isFaceMaterial === true
-							 ? objectMaterials.materials[ face.materialIndex ]
-							 : object.material;
-
-						if ( material === undefined ) continue;
-
-						var side = material.side;
-
-						var v1 = _vertexPool[ face.a ];
-						var v2 = _vertexPool[ face.b ];
-						var v3 = _vertexPool[ face.c ];
-
-						if ( renderList.checkTriangleVisibility( v1, v2, v3 ) === false ) continue;
-
-						var visible = renderList.checkBackfaceCulling( v1, v2, v3 );
-
-						if ( side !== THREE.DoubleSide ) {
-
-							if ( side === THREE.FrontSide && visible === false ) continue;
-							if ( side === THREE.BackSide && visible === true ) continue;
-
-						}
-
-						_face = getNextFaceInPool();
-
-						_face.id = object.id;
-						_face.v1.copy( v1 );
-						_face.v2.copy( v2 );
-						_face.v3.copy( v3 );
-
-						_face.normalModel.copy( face.normal );
-
-						if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) {
-
-							_face.normalModel.negate();
-
-						}
-
-						_face.normalModel.applyMatrix3( _normalMatrix ).normalize();
-
-						var faceVertexNormals = face.vertexNormals;
-
-						for ( var n = 0, nl = Math.min( faceVertexNormals.length, 3 ); n < nl; n ++ ) {
-
-							var normalModel = _face.vertexNormalsModel[ n ];
-							normalModel.copy( faceVertexNormals[ n ] );
-
-							if ( visible === false && ( side === THREE.BackSide || side === THREE.DoubleSide ) ) {
-
-								normalModel.negate();
-
-							}
-
-							normalModel.applyMatrix3( _normalMatrix ).normalize();
-
-						}
-
-						_face.vertexNormalsLength = faceVertexNormals.length;
-
-						var vertexUvs = faceVertexUvs[ f ];
-
-						if ( vertexUvs !== undefined ) {
-
-							for ( var u = 0; u < 3; u ++ ) {
-
-								_face.uvs[ u ].copy( vertexUvs[ u ] );
-
-							}
-
-						}
-
-						_face.color = face.color;
-						_face.material = material;
-
-						_face.z = ( v1.positionScreen.z + v2.positionScreen.z + v3.positionScreen.z ) / 3;
-						_face.renderOrder = object.renderOrder;
-
-						_renderData.elements.push( _face );
-
-					}
-
-				}
-
-			} else if ( object instanceof THREE.Line ) {
-
-				if ( geometry instanceof THREE.BufferGeometry ) {
-
-					var attributes = geometry.attributes;
-
-					if ( attributes.position !== undefined ) {
-
-						var positions = attributes.position.array;
-
-						for ( var i = 0, l = positions.length; i < l; i += 3 ) {
-
-							renderList.pushVertex( positions[ i ], positions[ i + 1 ], positions[ i + 2 ] );
-
-						}
-
-						if ( geometry.index !== null ) {
-
-							var indices = geometry.index.array;
-
-							for ( var i = 0, l = indices.length; i < l; i += 2 ) {
-
-								renderList.pushLine( indices[ i ], indices[ i + 1 ] );
-
-							}
-
-						} else {
-
-							var step = object instanceof THREE.LineSegments ? 2 : 1;
-
-							for ( var i = 0, l = ( positions.length / 3 ) - 1; i < l; i += step ) {
-
-								renderList.pushLine( i, i + 1 );
-
-							}
-
-						}
-
-					}
-
-				} else if ( geometry instanceof THREE.Geometry ) {
-
-					_modelViewProjectionMatrix.multiplyMatrices( _viewProjectionMatrix, _modelMatrix );
-
-					var vertices = object.geometry.vertices;
-
-					if ( vertices.length === 0 ) continue;
-
-					v1 = getNextVertexInPool();
-					v1.positionScreen.copy( vertices[ 0 ] ).applyMatrix4( _modelViewProjectionMatrix );
-
-					var step = object instanceof THREE.LineSegments ? 2 : 1;
-
-					for ( var v = 1, vl = vertices.length; v < vl; v ++ ) {
-
-						v1 = getNextVertexInPool();
-						v1.positionScreen.copy( vertices[ v ] ).applyMatrix4( _modelViewProjectionMatrix );
-
-						if ( ( v + 1 ) % step > 0 ) continue;
-
-						v2 = _vertexPool[ _vertexCount - 2 ];
-
-						_clippedVertex1PositionScreen.copy( v1.positionScreen );
-						_clippedVertex2PositionScreen.copy( v2.positionScreen );
-
-						if ( clipLine( _clippedVertex1PositionScreen, _clippedVertex2PositionScreen ) === true ) {
-
-							// Perform the perspective divide
-							_clippedVertex1PositionScreen.multiplyScalar( 1 / _clippedVertex1PositionScreen.w );
-							_clippedVertex2PositionScreen.multiplyScalar( 1 / _clippedVertex2PositionScreen.w );
-
-							_line = getNextLineInPool();
-
-							_line.id = object.id;
-							_line.v1.positionScreen.copy( _clippedVertex1PositionScreen );
-							_line.v2.positionScreen.copy( _clippedVertex2PositionScreen );
-
-							_line.z = Math.max( _clippedVertex1PositionScreen.z, _clippedVertex2PositionScreen.z );
-							_line.renderOrder = object.renderOrder;
-
-							_line.material = object.material;
-
-							if ( object.material.vertexColors === THREE.VertexColors ) {
-
-								_line.vertexColors[ 0 ].copy( object.geometry.colors[ v ] );
-								_line.vertexColors[ 1 ].copy( object.geometry.colors[ v - 1 ] );
-
-							}
-
-							_renderData.elements.push( _line );
-
-						}
-
-					}
-
-				}
-
-			} else if ( object instanceof THREE.Sprite ) {
-
-				_vector4.set( _modelMatrix.elements[ 12 ], _modelMatrix.elements[ 13 ], _modelMatrix.elements[ 14 ], 1 );
-				_vector4.applyMatrix4( _viewProjectionMatrix );
-
-				var invW = 1 / _vector4.w;
-
-				_vector4.z *= invW;
-
-				if ( _vector4.z >= - 1 && _vector4.z <= 1 ) {
-
-					_sprite = getNextSpriteInPool();
-					_sprite.id = object.id;
-					_sprite.x = _vector4.x * invW;
-					_sprite.y = _vector4.y * invW;
-					_sprite.z = _vector4.z;
-					_sprite.renderOrder = object.renderOrder;
-					_sprite.object = object;
-
-					_sprite.rotation = object.rotation;
-
-					_sprite.scale.x = object.scale.x * Math.abs( _sprite.x - ( _vector4.x + camera.projectionMatrix.elements[ 0 ] ) / ( _vector4.w + camera.projectionMatrix.elements[ 12 ] ) );
-					_sprite.scale.y = object.scale.y * Math.abs( _sprite.y - ( _vector4.y + camera.projectionMatrix.elements[ 5 ] ) / ( _vector4.w + camera.projectionMatrix.elements[ 13 ] ) );
-
-					_sprite.material = object.material;
-
-					_renderData.elements.push( _sprite );
-
-				}
-
-			}
-
-		}
-
-		if ( sortElements === true ) {
-
-			_renderData.elements.sort( painterSort );
-
-		}
-
-		return _renderData;
-
-	};
-
-	// Pools
-
-	function getNextObjectInPool() {
-
-		if ( _objectCount === _objectPoolLength ) {
-
-			var object = new THREE.RenderableObject();
-			_objectPool.push( object );
-			_objectPoolLength ++;
-			_objectCount ++;
-			return object;
-
-		}
-
-		return _objectPool[ _objectCount ++ ];
-
-	}
-
-	function getNextVertexInPool() {
-
-		if ( _vertexCount === _vertexPoolLength ) {
-
-			var vertex = new THREE.RenderableVertex();
-			_vertexPool.push( vertex );
-			_vertexPoolLength ++;
-			_vertexCount ++;
-			return vertex;
-
-		}
-
-		return _vertexPool[ _vertexCount ++ ];
-
-	}
-
-	function getNextFaceInPool() {
-
-		if ( _faceCount === _facePoolLength ) {
-
-			var face = new THREE.RenderableFace();
-			_facePool.push( face );
-			_facePoolLength ++;
-			_faceCount ++;
-			return face;
-
-		}
-
-		return _facePool[ _faceCount ++ ];
-
-
-	}
-
-	function getNextLineInPool() {
-
-		if ( _lineCount === _linePoolLength ) {
-
-			var line = new THREE.RenderableLine();
-			_linePool.push( line );
-			_linePoolLength ++;
-			_lineCount ++;
-			return line;
-
-		}
-
-		return _linePool[ _lineCount ++ ];
-
-	}
-
-	function getNextSpriteInPool() {
-
-		if ( _spriteCount === _spritePoolLength ) {
-
-			var sprite = new THREE.RenderableSprite();
-			_spritePool.push( sprite );
-			_spritePoolLength ++;
-			_spriteCount ++;
-			return sprite;
-
-		}
-
-		return _spritePool[ _spriteCount ++ ];
-
-	}
-
-	//
-
-	function painterSort( a, b ) {
-
-		if ( a.renderOrder !== b.renderOrder ) {
-
-			return a.renderOrder - b.renderOrder;
-
-		} else if ( a.z !== b.z ) {
-
-			return b.z - a.z;
-
-		} else if ( a.id !== b.id ) {
-
-			return a.id - b.id;
-
-		} else {
-
-			return 0;
-
-		}
-
-	}
-
-	function clipLine( s1, s2 ) {
-
-		var alpha1 = 0, alpha2 = 1,
-
-		// Calculate the boundary coordinate of each vertex for the near and far clip planes,
-		// Z = -1 and Z = +1, respectively.
-		bc1near =  s1.z + s1.w,
-		bc2near =  s2.z + s2.w,
-		bc1far =  - s1.z + s1.w,
-		bc2far =  - s2.z + s2.w;
-
-		if ( bc1near >= 0 && bc2near >= 0 && bc1far >= 0 && bc2far >= 0 ) {
-
-			// Both vertices lie entirely within all clip planes.
-			return true;
-
-		} else if ( ( bc1near < 0 && bc2near < 0 ) || ( bc1far < 0 && bc2far < 0 ) ) {
-
-			// Both vertices lie entirely outside one of the clip planes.
-			return false;
-
-		} else {
-
-			// The line segment spans at least one clip plane.
-
-			if ( bc1near < 0 ) {
-
-				// v1 lies outside the near plane, v2 inside
-				alpha1 = Math.max( alpha1, bc1near / ( bc1near - bc2near ) );
-
-			} else if ( bc2near < 0 ) {
-
-				// v2 lies outside the near plane, v1 inside
-				alpha2 = Math.min( alpha2, bc1near / ( bc1near - bc2near ) );
-
-			}
-
-			if ( bc1far < 0 ) {
-
-				// v1 lies outside the far plane, v2 inside
-				alpha1 = Math.max( alpha1, bc1far / ( bc1far - bc2far ) );
-
-			} else if ( bc2far < 0 ) {
-
-				// v2 lies outside the far plane, v2 inside
-				alpha2 = Math.min( alpha2, bc1far / ( bc1far - bc2far ) );
-
-			}
-
-			if ( alpha2 < alpha1 ) {
-
-				// The line segment spans two boundaries, but is outside both of them.
-				// (This can't happen when we're only clipping against just near/far but good
-				//  to leave the check here for future usage if other clip planes are added.)
-				return false;
-
-			} else {
-
-				// Update the s1 and s2 vertices to match the clipped line segment.
-				s1.lerp( s2, alpha1 );
-				s2.lerp( s1, 1 - alpha2 );
-
-				return true;
-
-			}
-
-		}
-
-	}
-
-};
-
-// END FILE:  Projector.js
-
-// BEGIN FILE:  AssimpJSONLoader.js
-/**
- * @author Alexander Gessler / http://www.greentoken.de/
- * https://github.com/acgessler
- *
- * Loader for models imported with Open Asset Import Library (http://assimp.sf.net)
- * through assimp2json (https://github.com/acgessler/assimp2json).
- *
- * Supports any input format that assimp supports, including 3ds, obj, dae, blend,
- * fbx, x, ms3d, lwo (and many more).
- *
- * See webgl_loader_assimp2json example.
- */
-
-THREE.AssimpJSONLoader = function ( manager ) {
-
-	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
-
-};
-
-THREE.AssimpJSONLoader.prototype = {
-
-	constructor: THREE.AssimpJSONLoader,
-
-	load: function ( url, onLoad, onProgress, onError ) {
-
-		var scope = this;
-
-		this.texturePath = this.texturePath && ( typeof this.texturePath === "string" ) ? this.texturePath : this.extractUrlBase( url );
-
-		var loader = new THREE.FileLoader( this.manager );
-		loader.load( url, function ( text ) {
-
-			var json = JSON.parse( text ), scene, metadata;
-
-			// Check __metadata__ meta header if present
-			// This header is used to disambiguate between
-			// different JSON-based file formats.
-			metadata = json.__metadata__;
-			if ( typeof metadata !== 'undefined' ) {
-
-				// Check if assimp2json at all
-				if ( metadata.format !== 'assimp2json' ) {
-
-					onError( 'Not an assimp2json scene' );
-					return;
-
-				}
-				// Check major format version
-				else if ( metadata.version < 100 && metadata.version >= 200 ) {
-
-					onError( 'Unsupported assimp2json file format version' );
-					return;
-
-				}
-
-			}
-
-			scene = scope.parse( json );
-			onLoad( scene );
-
-		}, onProgress, onError );
-
-	},
-
-	setCrossOrigin: function ( value ) {
-
-		this.crossOrigin = value;
-
-	},
-
-	setTexturePath: function ( value ) {
-
-		this.texturePath = value;
-
-	},
-
-	extractUrlBase: function ( url ) {
-
-		// from three/src/loaders/Loader.js
-		var parts = url.split( '/' );
-		parts.pop();
-		return ( parts.length < 1 ? '.' : parts.join( '/' ) ) + '/';
-
-	},
-
-	parse: function ( json ) {
-
-		var meshes = this.parseList ( json.meshes, this.parseMesh );
-		var materials = this.parseList ( json.materials, this.parseMaterial );
-		return this.parseObject( json, json.rootnode, meshes, materials );
-
-	},
-
-	parseList : function( json, handler ) {
-
-		var meshes = new Array( json.length );
-		for ( var i = 0; i < json.length; ++ i ) {
-
-			meshes[ i ] = handler.call( this, json[ i ] );
-
-		}
-		return meshes;
-
-	},
-
-	parseMesh : function( json ) {
-
-		var vertex, geometry, i, e, in_data, src;
-
-
-		geometry = new THREE.Geometry();
-
-		// read vertex positions
-		for ( in_data = json.vertices, i = 0, e = in_data.length; i < e; ) {
-
-			geometry.vertices.push( new THREE.Vector3( in_data[ i ++ ], in_data[ i ++ ], in_data[ i ++ ] ) );
-
-		}
-
-		// read faces
-		var cnt = 0;
-		for ( in_data = json.faces, i = 0, e = in_data.length; i < e; ++ i ) {
-
-			src = in_data[ i ];
-			face = new THREE.Face3( src[ 0 ], src[ 1 ], src[ 2 ] );
-			geometry.faces.push( face );
-
-		}
-
-		// read texture coordinates - three.js attaches them to its faces
-		json.texturecoords = json.texturecoords || [];
-		for ( i = 0, e = json.texturecoords.length; i < e; ++ i ) {
-
-			function convertTextureCoords( in_uv, out_faces, out_vertex_uvs ) {
-
-				var i, e, face, a, b, c;
-
-				for ( i = 0, e = out_faces.length; i < e; ++ i ) {
-
-					face = out_faces[ i ];
-					a = face.a * 2;
-					b = face.b * 2;
-					c = face.c * 2;
-					out_vertex_uvs.push( [
-						new THREE.Vector2( in_uv[ a ], in_uv[ a + 1 ] ),
-						new THREE.Vector2( in_uv[ b ], in_uv[ b + 1 ] ),
-						new THREE.Vector2( in_uv[ c ], in_uv[ c + 1 ] )
-					] );
-
-				}
-
-			}
-
-			convertTextureCoords( json.texturecoords[ i ], geometry.faces, geometry.faceVertexUvs[ i ] );
-
-		}
-
-		// read normals - three.js also attaches them to its faces
-		if ( json.normals ) {
-
-			function convertNormals( in_nor, out_faces ) {
-
-				var i, e, face, a, b, c;
-
-				for ( i = 0, e = out_faces.length; i < e; ++ i ) {
-
-					face = out_faces[ i ];
-					a = face.a * 3;
-					b = face.b * 3;
-					c = face.c * 3;
-					face.vertexNormals = [
-						new THREE.Vector3( in_nor[ a ], in_nor[ a + 1 ], in_nor[ a + 2 ] ),
-						new THREE.Vector3( in_nor[ b ], in_nor[ b + 1 ], in_nor[ b + 2 ] ),
-						new THREE.Vector3( in_nor[ c ], in_nor[ c + 1 ], in_nor[ c + 2 ] )
-					];
-
-				}
-
-			}
-
-			convertNormals( json.normals, geometry.faces );
-
-		}
-
-		// read vertex colors - three.js also attaches them to its faces
-		if ( json.colors && json.colors[ 0 ] ) {
-
-			function convertColors( in_color, out_faces ) {
-
-				for ( var i = 0, e = out_faces.length; i < e; ++ i ) {
-
-					var face = out_faces[ i ];
-					var a = face.a * 4;
-					var b = face.b * 4;
-					var c = face.c * 4;
-
-					face.vertexColors = [
-						new THREE.Color().fromArray( a ),
-						new THREE.Color().fromArray( b ),
-						new THREE.Color().fromArray( c )
-					];
-
-				}
-
-			}
-
-			convertColors( json.colors[ 0 ], geometry.faces );
-
-		}
-
-
-		//geometry.computeFaceNormals();
-		//geometry.computeVertexNormals();
-		geometry.computeBoundingSphere();
-
-		return geometry;
-
-	},
-
-	parseMaterial : function( json ) {
-
-		var mat = null,
-		scope = this, i, prop, has_textures = [],
-
-		init_props = {
-			shading : THREE.SmoothShading
-		};
-
-		function toColor( value_arr ) {
-
-			var col = new THREE.Color();
-			col.setRGB( value_arr[ 0 ], value_arr[ 1 ], value_arr[ 2 ] );
-			return col;
-
-		}
-
-		function defaultTexture() {
-
-			var im = new Image();
-			im.width = 1;
-			im.height = 1;
-			return new THREE.Texture( im );
-
-		}
-
-		for ( var i in json.properties ) {
-
-			prop = json.properties[ i ];
-
-			if ( prop.key === '$tex.file' ) {
-
-				// prop.semantic gives the type of the texture
-				// 1: diffuse
-				// 2: specular mao
-				// 5: height map (bumps)
-				// 6: normal map
-				// more values (i.e. emissive, environment) are known by assimp and may be relevant
-				if ( prop.semantic === 1 || prop.semantic === 5 || prop.semantic === 6 || prop.semantic === 2 ) {
-
-					( function( semantic ) {
-
-						var loader = new THREE.TextureLoader( scope.manager ),
-						keyname;
-
-						if ( semantic === 1 ) {
-
-							keyname = 'map';
-
-						} else if ( semantic === 5 ) {
-
-							keyname = 'bumpMap';
-
-						} else if ( semantic === 6 ) {
-
-							keyname = 'normalMap';
-
-						} else if ( semantic === 2 ) {
-
-							keyname = 'specularMap';
-
-						}
-
-						has_textures.push( keyname );
-
-						loader.setCrossOrigin( this.crossOrigin );
-						var material_url = scope.texturePath + '/' + prop.value;
-						material_url = material_url.replace( /\\/g, '/' );
-						loader.load( material_url, function( tex ) {
-
-							if ( tex ) {
-
-								// TODO: read texture settings from assimp.
-								// Wrapping is the default, though.
-								tex.wrapS = tex.wrapT = THREE.RepeatWrapping;
-
-								mat[ keyname ] = tex;
-								mat.needsUpdate = true;
-
-							}
-
-						} );
-
-					} )( prop.semantic );
-
-				}
-
-			} else if ( prop.key === '?mat.name' ) {
-
-				init_props.name = prop.value;
-
-			} else if ( prop.key === '$clr.diffuse' ) {
-
-				init_props.color = toColor( prop.value );
-
-			} else if ( prop.key === '$clr.specular' ) {
-
-				init_props.specular = toColor( prop.value );
-
-			} else if ( prop.key === '$clr.emissive' ) {
-
-				init_props.emissive = toColor( prop.value );
-
-			} else if ( prop.key === '$mat.shadingm' ) {
-
-				// aiShadingMode_Flat
-				if ( prop.value === 1 ) {
-
-					init_props.shading = THREE.FlatShading;
-
-				}
-
-			} else if ( prop.key === '$mat.shininess' ) {
-
-				init_props.shininess = prop.value;
-
-			}
-
-		}
-
-		// note: three.js does not like it when a texture is added after the geometry
-		// has been rendered once, see http://stackoverflow.com/questions/16531759/.
-		// for this reason we fill all slots upfront with default textures
-		if ( has_textures.length ) {
-
-			for ( i = has_textures.length - 1; i >= 0; -- i ) {
-
-				init_props[ has_textures[ i ]] = defaultTexture();
-
-			}
-
-		}
-
-		mat = new THREE.MeshPhongMaterial( init_props );
-		return mat;
-
-	},
-
-	parseObject : function( json, node, meshes, materials ) {
-
-		var obj = new THREE.Object3D()
-		,	i
-		,	idx
-		;
-
-		obj.name = node.name || "";
-		obj.matrix = new THREE.Matrix4().fromArray( node.transformation ).transpose();
-		obj.matrix.decompose( obj.position, obj.quaternion, obj.scale );
-
-		for ( i = 0; node.meshes && i < node.meshes.length; ++ i ) {
-
-			idx = node.meshes[ i ];
-			obj.add( new THREE.Mesh( meshes[ idx ], materials[ json.meshes[ idx ].materialindex ] ) );
-
-		}
-
-		for ( i = 0; node.children && i < node.children.length; ++ i ) {
-
-			obj.add( this.parseObject( json, node.children[ i ], meshes, materials ) );
-
-		}
-
-		return obj;
-
-	},
-};
-
-
-// END FILE:  AssimpJSONLoader.js
-
-
-// BEGIN FILE:  Tween.js
-/**
- * Tween.js - Licensed under the MIT license
- * https://github.com/sole/tween.js
- * ----------------------------------------------
- *
- * See https://github.com/sole/tween.js/graphs/contributors for the full list of contributors.
- * Thank you all, you're awesome!
- */
-
-( function ( root ) {
-
-	if ( 'performance' in root === false ) {
-		root.performance = {};
-	}
-
-	// IE 8
-	Date.now = ( Date.now || function () {
-		return new Date().getTime();
-	} );
-
-	if ( 'now' in root.performance === false ) {
-		var offset = root.performance.timing && root.performance.timing.navigationStart ? performance.timing.navigationStart
-		                                                                                : Date.now();
-
-		root.performance.now = function () {
-			return Date.now() - offset;
-		};
-	}
-
-} )( this );
-
-var TWEEN = TWEEN || ( function () {
-
-	var _tweens = [];
-
-	return {
-
-		REVISION: '14',
-
-		getAll: function () {
-
-			return _tweens;
-
-		},
-
-		removeAll: function () {
-
-			_tweens = [];
-
-		},
-
-		add: function ( tween ) {
-
-			_tweens.push( tween );
-
-		},
-
-		remove: function ( tween ) {
-
-			var i = _tweens.indexOf( tween );
-
-			if ( i !== -1 ) {
-
-				_tweens.splice( i, 1 );
-
-			}
-
-		},
-
-		update: function ( time ) {
-
-			if ( _tweens.length === 0 ) return false;
-
-			var i = 0;
-
-			time = time !== undefined ? time : window.performance.now();
-
-			while ( i < _tweens.length ) {
-
-				if ( _tweens[ i ].update( time ) ) {
-
-					i++;
-
-				} else {
-
-					_tweens.splice( i, 1 );
-
-				}
-
-			}
-
-			return true;
-
-		}
-	};
-
-} )();
-
-TWEEN.Tween = function ( object ) {
-
-	var _object = object;
-	var _valuesStart = {};
-	var _valuesEnd = {};
-	var _valuesStartRepeat = {};
-	var _duration = 1000;
-	var _repeat = 0;
-	var _yoyo = false;
-	var _isPlaying = false;
-	var _reversed = false;
-	var _delayTime = 0;
-	var _startTime = null;
-	var _easingFunction = TWEEN.Easing.Linear.None;
-	var _interpolationFunction = TWEEN.Interpolation.Linear;
-	var _chainedTweens = [];
-	var _onStartCallback = null;
-	var _onStartCallbackFired = false;
-	var _onUpdateCallback = null;
-	var _onCompleteCallback = null;
-	var _onStopCallback = null;
-
-	// Set all starting values present on the target object
-	for ( var field in object ) {
-
-		_valuesStart[ field ] = parseFloat(object[field], 10);
-
-	}
-
-	this.to = function ( properties, duration ) {
-
-		if ( duration !== undefined ) {
-
-			_duration = duration;
-
-		}
-
-		_valuesEnd = properties;
-
-		return this;
-
-	};
-
-	this.start = function ( time ) {
-
-		TWEEN.add( this );
-
-		_isPlaying = true;
-
-		_onStartCallbackFired = false;
-
-		_startTime = time !== undefined ? time : window.performance.now();
-		_startTime += _delayTime;
-
-		for ( var property in _valuesEnd ) {
-
-			// check if an Array was provided as property value
-			if ( _valuesEnd[ property ] instanceof Array ) {
-
-				if ( _valuesEnd[ property ].length === 0 ) {
-
-					continue;
-
-				}
-
-				// create a local copy of the Array with the start value at the front
-				_valuesEnd[ property ] = [ _object[ property ] ].concat( _valuesEnd[ property ] );
-
-			}
-
-			_valuesStart[ property ] = _object[ property ];
-
-			if( ( _valuesStart[ property ] instanceof Array ) === false ) {
-				_valuesStart[ property ] *= 1.0; // Ensures we're using numbers, not strings
-			}
-
-			_valuesStartRepeat[ property ] = _valuesStart[ property ] || 0;
-
-		}
-
-		return this;
-
-	};
-
-	this.stop = function () {
-
-		if ( !_isPlaying ) {
-			return this;
-		}
-
-		TWEEN.remove( this );
-		_isPlaying = false;
-
-		if ( _onStopCallback !== null ) {
-
-			_onStopCallback.call( _object );
-
-		}
-
-		this.stopChainedTweens();
-		return this;
-
-	};
-
-	this.stopChainedTweens = function () {
-
-		for ( var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++ ) {
-
-			_chainedTweens[ i ].stop();
-
-		}
-
-	};
-
-	this.delay = function ( amount ) {
-
-		_delayTime = amount;
-		return this;
-
-	};
-
-	this.repeat = function ( times ) {
-
-		_repeat = times;
-		return this;
-
-	};
-
-	this.yoyo = function( yoyo ) {
-
-		_yoyo = yoyo;
-		return this;
-
-	};
-
-
-	this.easing = function ( easing ) {
-
-		_easingFunction = easing;
-		return this;
-
-	};
-
-	this.interpolation = function ( interpolation ) {
-
-		_interpolationFunction = interpolation;
-		return this;
-
-	};
-
-	this.chain = function () {
-
-		_chainedTweens = arguments;
-		return this;
-
-	};
-
-	this.onStart = function ( callback ) {
-
-		_onStartCallback = callback;
-		return this;
-
-	};
-
-	this.onUpdate = function ( callback ) {
-
-		_onUpdateCallback = callback;
-		return this;
-
-	};
-
-	this.onComplete = function ( callback ) {
-
-		_onCompleteCallback = callback;
-		return this;
-
-	};
-
-	this.onStop = function ( callback ) {
-
-		_onStopCallback = callback;
-		return this;
-
-	};
-
-	this.update = function ( time ) {
-
-		var property;
-
-		if ( time < _startTime ) {
-
-			return true;
-
-		}
-
-		if ( _onStartCallbackFired === false ) {
-
-			if ( _onStartCallback !== null ) {
-
-				_onStartCallback.call( _object );
-
-			}
-
-			_onStartCallbackFired = true;
-
-		}
-
-		var elapsed = ( time - _startTime ) / _duration;
-		elapsed = elapsed > 1 ? 1 : elapsed;
-
-		var value = _easingFunction( elapsed );
-
-		for ( property in _valuesEnd ) {
-
-			var start = _valuesStart[ property ] || 0;
-			var end = _valuesEnd[ property ];
-
-			if ( end instanceof Array ) {
-
-				_object[ property ] = _interpolationFunction( end, value );
-
-			} else {
-
-				// Parses relative end values with start as base (e.g.: +10, -3)
-				if ( typeof(end) === "string" ) {
-					end = start + parseFloat(end, 10);
-				}
-
-				// protect against non numeric properties.
-				if ( typeof(end) === "number" ) {
-					_object[ property ] = start + ( end - start ) * value;
-				}
-
-			}
-
-		}
-
-		if ( _onUpdateCallback !== null ) {
-
-			_onUpdateCallback.call( _object, value );
-
-		}
-
-		if ( elapsed == 1 ) {
-
-			if ( _repeat > 0 ) {
-
-				if( isFinite( _repeat ) ) {
-					_repeat--;
-				}
-
-				// reassign starting values, restart by making startTime = now
-				for( property in _valuesStartRepeat ) {
-
-					if ( typeof( _valuesEnd[ property ] ) === "string" ) {
-						_valuesStartRepeat[ property ] = _valuesStartRepeat[ property ] + parseFloat(_valuesEnd[ property ], 10);
-					}
-
-					if (_yoyo) {
-						var tmp = _valuesStartRepeat[ property ];
-						_valuesStartRepeat[ property ] = _valuesEnd[ property ];
-						_valuesEnd[ property ] = tmp;
-					}
-
-					_valuesStart[ property ] = _valuesStartRepeat[ property ];
-
-				}
-
-				if (_yoyo) {
-					_reversed = !_reversed;
-				}
-
-				_startTime = time + _delayTime;
-
-				return true;
-
-			} else {
-
-				if ( _onCompleteCallback !== null ) {
-
-					_onCompleteCallback.call( _object );
-
-				}
-
-				for ( var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++ ) {
-
-					_chainedTweens[ i ].start( time );
-
-				}
-
-				return false;
-
-			}
-
-		}
-
-		return true;
-
-	};
-
-};
-
-
-TWEEN.Easing = {
-
-	Linear: {
-
-		None: function ( k ) {
-
-			return k;
-
-		}
-
-	},
-
-	Quadratic: {
-
-		In: function ( k ) {
-
-			return k * k;
-
-		},
-
-		Out: function ( k ) {
-
-			return k * ( 2 - k );
-
-		},
-
-		InOut: function ( k ) {
-
-			if ( ( k *= 2 ) < 1 ) return 0.5 * k * k;
-			return - 0.5 * ( --k * ( k - 2 ) - 1 );
-
-		}
-
-	},
-
-	Cubic: {
-
-		In: function ( k ) {
-
-			return k * k * k;
-
-		},
-
-		Out: function ( k ) {
-
-			return --k * k * k + 1;
-
-		},
-
-		InOut: function ( k ) {
-
-			if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k;
-			return 0.5 * ( ( k -= 2 ) * k * k + 2 );
-
-		}
-
-	},
-
-	Quartic: {
-
-		In: function ( k ) {
-
-			return k * k * k * k;
-
-		},
-
-		Out: function ( k ) {
-
-			return 1 - ( --k * k * k * k );
-
-		},
-
-		InOut: function ( k ) {
-
-			if ( ( k *= 2 ) < 1) return 0.5 * k * k * k * k;
-			return - 0.5 * ( ( k -= 2 ) * k * k * k - 2 );
-
-		}
-
-	},
-
-	Quintic: {
-
-		In: function ( k ) {
-
-			return k * k * k * k * k;
-
-		},
-
-		Out: function ( k ) {
-
-			return --k * k * k * k * k + 1;
-
-		},
-
-		InOut: function ( k ) {
-
-			if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k * k * k;
-			return 0.5 * ( ( k -= 2 ) * k * k * k * k + 2 );
-
-		}
-
-	},
-
-	Sinusoidal: {
-
-		In: function ( k ) {
-
-			return 1 - Math.cos( k * Math.PI / 2 );
-
-		},
-
-		Out: function ( k ) {
-
-			return Math.sin( k * Math.PI / 2 );
-
-		},
-
-		InOut: function ( k ) {
-
-			return 0.5 * ( 1 - Math.cos( Math.PI * k ) );
-
-		}
-
-	},
-
-	Exponential: {
-
-		In: function ( k ) {
-
-			return k === 0 ? 0 : Math.pow( 1024, k - 1 );
-
-		},
-
-		Out: function ( k ) {
-
-			return k === 1 ? 1 : 1 - Math.pow( 2, - 10 * k );
-
-		},
-
-		InOut: function ( k ) {
-
-			if ( k === 0 ) return 0;
-			if ( k === 1 ) return 1;
-			if ( ( k *= 2 ) < 1 ) return 0.5 * Math.pow( 1024, k - 1 );
-			return 0.5 * ( - Math.pow( 2, - 10 * ( k - 1 ) ) + 2 );
-
-		}
-
-	},
-
-	Circular: {
-
-		In: function ( k ) {
-
-			return 1 - Math.sqrt( 1 - k * k );
-
-		},
-
-		Out: function ( k ) {
-
-			return Math.sqrt( 1 - ( --k * k ) );
-
-		},
-
-		InOut: function ( k ) {
-
-			if ( ( k *= 2 ) < 1) return - 0.5 * ( Math.sqrt( 1 - k * k) - 1);
-			return 0.5 * ( Math.sqrt( 1 - ( k -= 2) * k) + 1);
-
-		}
-
-	},
-
-	Elastic: {
-
-		In: function ( k ) {
-
-			var s, a = 0.1, p = 0.4;
-			if ( k === 0 ) return 0;
-			if ( k === 1 ) return 1;
-			if ( !a || a < 1 ) { a = 1; s = p / 4; }
-			else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI );
-			return - ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) );
-
-		},
-
-		Out: function ( k ) {
-
-			var s, a = 0.1, p = 0.4;
-			if ( k === 0 ) return 0;
-			if ( k === 1 ) return 1;
-			if ( !a || a < 1 ) { a = 1; s = p / 4; }
-			else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI );
-			return ( a * Math.pow( 2, - 10 * k) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) + 1 );
-
-		},
-
-		InOut: function ( k ) {
-
-			var s, a = 0.1, p = 0.4;
-			if ( k === 0 ) return 0;
-			if ( k === 1 ) return 1;
-			if ( !a || a < 1 ) { a = 1; s = p / 4; }
-			else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI );
-			if ( ( k *= 2 ) < 1 ) return - 0.5 * ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) );
-			return a * Math.pow( 2, -10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) * 0.5 + 1;
-
-		}
-
-	},
-
-	Back: {
-
-		In: function ( k ) {
-
-			var s = 1.70158;
-			return k * k * ( ( s + 1 ) * k - s );
-
-		},
-
-		Out: function ( k ) {
-
-			var s = 1.70158;
-			return --k * k * ( ( s + 1 ) * k + s ) + 1;
-
-		},
-
-		InOut: function ( k ) {
-
-			var s = 1.70158 * 1.525;
-			if ( ( k *= 2 ) < 1 ) return 0.5 * ( k * k * ( ( s + 1 ) * k - s ) );
-			return 0.5 * ( ( k -= 2 ) * k * ( ( s + 1 ) * k + s ) + 2 );
-
-		}
-
-	},
-
-	Bounce: {
-
-		In: function ( k ) {
-
-			return 1 - TWEEN.Easing.Bounce.Out( 1 - k );
-
-		},
-
-		Out: function ( k ) {
-
-			if ( k < ( 1 / 2.75 ) ) {
-
-				return 7.5625 * k * k;
-
-			} else if ( k < ( 2 / 2.75 ) ) {
-
-				return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75;
-
-			} else if ( k < ( 2.5 / 2.75 ) ) {
-
-				return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375;
-
-			} else {
-
-				return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375;
-
-			}
-
-		},
-
-		InOut: function ( k ) {
-
-			if ( k < 0.5 ) return TWEEN.Easing.Bounce.In( k * 2 ) * 0.5;
-			return TWEEN.Easing.Bounce.Out( k * 2 - 1 ) * 0.5 + 0.5;
-
-		}
-
-	}
-
-};
-
-TWEEN.Interpolation = {
-
-	Linear: function ( v, k ) {
-
-		var m = v.length - 1, f = m * k, i = Math.floor( f ), fn = TWEEN.Interpolation.Utils.Linear;
-
-		if ( k < 0 ) return fn( v[ 0 ], v[ 1 ], f );
-		if ( k > 1 ) return fn( v[ m ], v[ m - 1 ], m - f );
-
-		return fn( v[ i ], v[ i + 1 > m ? m : i + 1 ], f - i );
-
-	},
-
-	Bezier: function ( v, k ) {
-
-		var b = 0, n = v.length - 1, pw = Math.pow, bn = TWEEN.Interpolation.Utils.Bernstein, i;
-
-		for ( i = 0; i <= n; i++ ) {
-			b += pw( 1 - k, n - i ) * pw( k, i ) * v[ i ] * bn( n, i );
-		}
-
-		return b;
-
-	},
-
-	CatmullRom: function ( v, k ) {
-
-		var m = v.length - 1, f = m * k, i = Math.floor( f ), fn = TWEEN.Interpolation.Utils.CatmullRom;
-
-		if ( v[ 0 ] === v[ m ] ) {
-
-			if ( k < 0 ) i = Math.floor( f = m * ( 1 + k ) );
-
-			return fn( v[ ( i - 1 + m ) % m ], v[ i ], v[ ( i + 1 ) % m ], v[ ( i + 2 ) % m ], f - i );
-
-		} else {
-
-			if ( k < 0 ) return v[ 0 ] - ( fn( v[ 0 ], v[ 0 ], v[ 1 ], v[ 1 ], -f ) - v[ 0 ] );
-			if ( k > 1 ) return v[ m ] - ( fn( v[ m ], v[ m ], v[ m - 1 ], v[ m - 1 ], f - m ) - v[ m ] );
-
-			return fn( v[ i ? i - 1 : 0 ], v[ i ], v[ m < i + 1 ? m : i + 1 ], v[ m < i + 2 ? m : i + 2 ], f - i );
-
-		}
-
-	},
-
-	Utils: {
-
-		Linear: function ( p0, p1, t ) {
-
-			return ( p1 - p0 ) * t + p0;
-
-		},
-
-		Bernstein: function ( n , i ) {
-
-			var fc = TWEEN.Interpolation.Utils.Factorial;
-			return fc( n ) / fc( i ) / fc( n - i );
-
-		},
-
-		Factorial: ( function () {
-
-			var a = [ 1 ];
-
-			return function ( n ) {
-
-				var s = 1, i;
-				if ( a[ n ] ) return a[ n ];
-				for ( i = n; i > 1; i-- ) s *= i;
-				return a[ n ] = s;
-
-			};
-
-		} )(),
-
-		CatmullRom: function ( p0, p1, p2, p3, t ) {
-
-			var v0 = ( p2 - p0 ) * 0.5, v1 = ( p3 - p1 ) * 0.5, t2 = t * t, t3 = t * t2;
-			return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;
-
-		}
-
-	}
-
-};
-
-// UMD (Universal Module Definition)
-( function ( root ) {
-
-	if ( typeof define === 'function' && define.amd ) {
-
-		// AMD
-		define( [], function () {
-			return TWEEN;
-		} );
-
-	} else if ( typeof exports === 'object' ) {
-
-		// Node.js
-		module.exports = TWEEN;
-
-	} else {
-
-		// Global variable
-		root.TWEEN = TWEEN;
-
-	}
-
-} )( this );
-
-// END FILE:  Tween.js
diff --git a/js/awe-standard.js b/js/awe-standard.js
deleted file mode 100644
index a634996..0000000
--- a/js/awe-standard.js
+++ /dev/null
@@ -1,4472 +0,0 @@
-/*
-
-  The MIT License
-
-  Copyright (c) 2013 Rob Manson & Malgorzata Wierzbicka, http://buildAR.com. 
-  All rights reserved.
-
-  Permission is hereby granted, free of charge, to any person obtaining a copy
-  of this software and associated documentation files (the "Software"), to deal
-  in the Software without restriction, including without limitation the rights
-  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-  copies of the Software, and to permit persons to whom the Software is
-  furnished to do so, subject to the following conditions:
-
-  The above copyright notice and this permission notice shall be included in
-  all copies or substantial portions of the Software.
-
-  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-  THE SOFTWARE.
-
-*/
-
-(function(window) {
-  if (window.awe) {
-    var undefined;
-    var this_awe;
-    
-    var _extend,
-      _clone,
-      _clone_deep,
-      _type,
-      _tween_queue;
-    
-    var noop = function(){};
-    var this_awe = window.awe;
-    var _clickable_objects = {};
-    var loading_manager;
-    var texture_loading_progress = function(xhr){},
-      texture_loading_error = function(){};
-      
-    var frustum;
-    var cameraViewProjectionMatrix;
-    var inline_video_shim_required = !!(navigator.userAgent.match(/iphone/ig));
-    function inline_video_shim_toggle(video, val){
-      if (video._playing != val) {
-        video._playing = val; 
-
-        // trigger events manually
-        var event_name = val ? ( video.currentTime == 0 ? 'playing' : 'play') : 'pause';
-        video.dispatchEvent(new CustomEvent(event_name));
-      }
-    }
-    
-    this_awe.OBJECT_STATES = {
-      INITIAL: 'initial',
-      LOADING: 'loading',
-      LOADED: 'loaded',
-      LOWRES: 'low_res', // not all objects have this state, applies only to objects that have a low-res fallback option 
-      DEFAULT: 'default',
-      ACTIVE: 'active',
-      INACTIVE: 'inactive'
-    };
-
-    // renderer class
-    function awe_renderer(data, datastore){
-      awe_object.call(this, data, datastore);
-      var canvas = this.get_canvas();
-      if (canvas) {
-        this.canvas_width = canvas.clientWidth;
-        this.canvas_height = canvas.clientHeight;
-      }
-    }
-    awe_renderer.prototype = Object.create(awe_object.prototype);
-    awe_renderer.prototype.constructor = awe_renderer;
-    awe_renderer.prototype.get_three_renderer = function(){
-      return this._get_data_value('three_renderer');
-    };
-    awe_renderer.prototype.get_canvas = function(){
-      var three_renderer = this.get_three_renderer();
-      return three_renderer.domElement;
-    };
-    awe_renderer.prototype.update = function(BODY, HEAD){
-      awe_object.prototype.update.call(this, BODY, HEAD);
-      // update any shortcut params we'd like to have exposed
-      var canvas = this.get_canvas();
-      if (canvas) {
-        this.canvas_width = canvas.clientWidth;
-        this.canvas_height = canvas.clientHeight;
-      }
-    };
-    awe_renderer.prototype.set_size = function(width, height, inline_css){
-      var three_renderer = this.get_three_renderer();
-      three_renderer.setSize(width, height, inline_css);
-      var canvas = this.get_canvas();
-      if (canvas) {
-        this.canvas_width = canvas.clientWidth;
-        this.canvas_height = canvas.clientHeight;
-      }
-    };
-    awe_renderer.prototype.set_clear_color = function(clear_color, opacity){
-      var three_renderer = this.get_three_renderer();
-      three_renderer.setClearColor( clear_color, opacity );
-    };
-    awe_renderer.prototype.set_shadow_map_type = function(shadow_map_type){
-      var three_renderer = this.get_three_renderer();
-      three_renderer.shadowMapEnabled = true;
-      
-      switch(shadow_map_type) {
-        case 'basic':
-          three_renderer.shadowMapType = THREE.BasicShadowMap;                
-          break;
-        case 'pcf':
-          three_renderer.shadowMapType = THREE.PCFShadowMap;                
-          break;
-        case 'pcf_soft':
-          three_renderer.shadowMapType = THREE.PCFSoftShadowMap;                
-          break;
-        default:
-          throw { code: 500, message: 'shadow_map_type unsupported' };
-          break;
-      }
-    };
-    awe_renderer.prototype.render = function(awe_scene, awe_pov){
-      var three_renderer = this.get_three_renderer();
-      three_renderer.render( awe_scene.get_three_scene(), awe_pov.get_mesh() );
-    };
-    
-    
-    // awe_video_stream class
-    function awe_video_stream(data, datastore){
-      awe_object.call(this, data, datastore);
-    }
-    awe_video_stream.prototype = Object.create(awe_object.prototype);
-    awe_video_stream.prototype.constructor = awe_video_stream;
-    awe_video_stream.prototype.attach_target = function(video_element, identifier){
-      var stream = this._get_data_value('stream');
-      if (stream) {
-        this_awe.util.connect_stream_to_src(stream, video_element, identifier);
-      }
-    };
-    awe_video_stream.prototype.detach_target = function(video_element, identifier){
-      this_awe.util.disconnect_stream(video_element, identifier);
-    };
-    awe_video_stream.prototype.is_stream_ready = function(){
-      var v = this.get_video_element(),
-        s = this.get_stream(),
-        active = false;
-      // firefox on android does not have stream.active
-      if (v && s) {
-        try {
-          if (s.active) {
-            active = true;
-          }
-          else if (s.getVideoTracks) {
-            var tracks = s.getVideoTracks();
-            tracks.forEach(function(track){
-              if (track.enabled) {
-                active = true;
-              }
-            });
-          }
-        }
-        catch(e){}
-      }
-      return active;
-    };
-    awe_video_stream.prototype.get_video_element = function(){
-      return this._get_data_value('video_element');
-    };
-    awe_video_stream.prototype.get_stream = function(){
-      return this._get_data_value('stream');
-    };
-    awe_video_stream.prototype.stop = function(){
-      awe.video_streams.delete(this.id);
-    };
-    
-    // awe_scene class
-    function awe_scene(data, datastore){
-      awe_object.call(this, data, datastore);
-      this.init();
-    }
-    awe_scene.prototype = Object.create(awe_object.prototype);
-    awe_scene.prototype.constructor = awe_scene;
-    awe_scene.prototype.three_children = function(){
-      var three_scene = this._get_data_value('three_scene');
-      return three_scene.children;
-    };
-    awe_scene.prototype.init = function(){
-      
-    };
-    awe_scene.prototype.get_three_scene = function(){
-      return this._get_data_value('three_scene');
-    };
-    awe_scene.prototype.get_mesh = function(){
-      return this.get_three_scene();
-    };
-    awe_scene.prototype.add = function(object){
-      var mesh;
-      if (object instanceof awe_mesh_object) {
-        mesh = object.get_mesh();
-      }
-      else if (object instanceof THREE.Object3D){
-        mesh = object;
-      }
-      if (mesh) {
-        var scene_mesh = this.get_mesh();
-        scene_mesh.add(mesh);
-        return true;
-      }
-      else {
-        console.warn('cannot add object to scene', object)
-      }
-      return false;
-    };
-    awe_scene.prototype.remove = function(object){
-      var mesh;
-      if (object instanceof awe_mesh_object) {
-        mesh = object.get_mesh();
-      }
-      else if (object instanceof THREE.Object3D){
-        mesh = object;
-      }
-      if (mesh) {
-        var three_scene = this._get_data_value('three_scene');
-        three_scene.remove(mesh);
-        return true;
-      }
-      return false;
-    };
-    awe_scene.prototype._add_child = function(child){
-      var my_mesh = this.get_mesh();
-      var new_mesh = child instanceof THREE.Object3D ? child : child.get_mesh();
-      my_mesh.add(new_mesh);
-      this_awe.scene_needs_rendering = 1;      
-    };
-    awe_scene.prototype._remove_child = function(child){
-      var my_mesh = this.get_mesh();
-      var new_mesh = child instanceof THREE.Object3D ? child : child.get_mesh();
-      my_mesh.remove(new_mesh);
-      this_awe.scene_needs_rendering = 1;      
-    };
-    
-    
-    // awe_texture class
-    function awe_texture(data, datastore){
-      awe_object.call(this, data, datastore);
-      this.texture = data.texture;
-    }
-    awe_texture.prototype = Object.create(awe_object.prototype);
-    awe_texture.prototype.constructor = awe_texture;
-    awe_texture.prototype.value = function(){
-      return this._get_data_value('texture');
-    };
-    awe_texture.prototype.is_video_texture = function(){
-      var three_texture = this.value();
-      return !!three_texture.video;
-    };
-    awe_texture.prototype.autoplay = function(){
-      var three_texture = this.value();
-      return !!(three_texture.video && three_texture.video.autoplay);
-    };
-    awe_texture.prototype.play = function(){
-      if (this.is_video_texture()) {
-        var three_texture = this.value();
-        this.paused = false;
-        if (three_texture.video && three_texture.video.getAttribute('data-sourcetype') != 'camerastream') {
-          inline_video_shim_toggle(three_texture.video, true);
-          if (!inline_video_shim_required) {
-            three_texture.video.play();
-          }
-        }
-        else {
-          var self = this
-          var go = function(){
-            window.removeEventListener('gum_ready', go, false);
-            if (!self.paused) {
-              this_awe.util.connect_stream_to_src(this_awe.video_stream().get_stream(), three_texture.video, self.id);
-            }
-          }
-          if (this_awe.video_stream() && this_awe.video_stream().is_stream_ready()) {
-            go();
-          }
-          else {
-            this_awe.setup_stream();
-            window.addEventListener('gum_ready', go, false);
-          }
-
-        }
-      }
-    };
-    awe_texture.prototype.pause = function(){
-      if (this.is_video_texture()) {
-        var three_texture = this.value();
-        this.paused = true;
-        if (three_texture.video && three_texture.video.getAttribute('data-sourcetype') != 'camerastream') {
-          try {
-            // we should not pause video stream textures, the stream video will get paused in effect
-            inline_video_shim_toggle(three_texture.video, false);
-            if (!inline_video_shim_required) {
-              three_texture.video.pause();
-            }
-          }
-          catch(e) {}
-        }
-        else {
-          this_awe.util.disconnect_stream(three_texture.video, this.id);
-        }
-      }
-    };
-    awe_texture.prototype.stop = function(){
-      if (this.is_video_texture()) {
-        var three_texture = this.value();
-        if (three_texture.video && three_texture.video.getAttribute('data-sourcetype') != 'camerastream') {
-          try {
-            inline_video_shim_toggle(three_texture.video, false);
-            if (!inline_video_shim_required) {
-              three_texture.video.pause();
-            }
-
-            three_texture.video.last_time = 0;
-            three_texture.video.currentTime = 0;
-          }
-          catch(e) {}
-        }
-        else {
-          this_awe.util.disconnect_stream(three_texture.video);
-        }
-      }
-    };
-    awe_texture.prototype.update_video_texture = function(){
-      var three_texture = this.value();
-      var result = false;
-//        console.log('readystate', three_texture.video.readyState, three_texture.video.HAVE_ENOUGH_DATA)
-      if (three_texture.video && three_texture.video.readyState === three_texture.video.HAVE_ENOUGH_DATA) {
-
-        if (inline_video_shim_required && three_texture.video._playing && three_texture.video.duration) { // manually progress through the video
-          // trigger the 'playing' event manually
-           
-          var frames_per_second = 25;
-          var time = Date.now();
-          if (three_texture.video.last_time) {
-            var elapsed = (time - three_texture.video.last_time) / 1000;
-            if (elapsed >= ((1000/frames_per_second)/1000)) {
-              three_texture.video.currentTime = three_texture.video.currentTime + elapsed;
-            }
-            // if we are at the end of the video -> stop OR loop
-            var currentTime = (Math.round(parseFloat(three_texture.video.currentTime)*10000)/10000);
-            var duration = (Math.round(parseFloat(three_texture.video.duration)*10000)/10000);
-            if (currentTime >= duration) {
-              three_texture.video.last_time = 0;
-              three_texture.video.currentTime = 0;
-              if (!three_texture.video.loop) {
-                inline_video_shim_toggle(three_texture.video, false);
-              }
-              return;
-            }
-          }
-          three_texture.video.last_time = time;
-          
-        }
-/*
-        if (three_texture.video.getAttribute('data-sourcetype') == 'camerastream' && !this_awe.video_stream()) {
-//           this_awe.setup_stream();
-
-        }
-*/
-        if (three_texture.cc) {
-          try {
-            three_texture.cc.drawImage(three_texture.video, 0, 0, three_texture.cc.canvas.width, three_texture.cc.canvas.height);
-            three_texture.needsUpdate = true;
-            result = true;
-          }
-          catch(e) { };
-        }
-      }
-      return result;
-    };
-    
-    // awe_material class
-    function awe_material(data, datastore){
-      awe_object.call(this, data, datastore);
-      this.material = data.material;
-    }
-    awe_material.prototype = Object.create(awe_object.prototype);
-    awe_material.prototype.constructor = awe_material;
-    awe_material.prototype.value = function(){
-      return this._get_data_value('material');
-    };
-    
-    // awe_sound class
-    function awe_sound(data, datastore){
-      awe_object.call(this, data, datastore);
-    }
-    awe_sound.prototype = Object.create(awe_object.prototype);
-    awe_sound.prototype.constructor = awe_sound;
-    
-    
-    // awe_mesh_object class
-    function awe_mesh_object(data, datastore){
-      awe_object.call(this, data, datastore);
-      this.children = [];
-      this._tweens = {};
-      
-      this._values_updated();
-      /*
-// TODO - wire up direct click handling
-      if (data.click_handlers) {
-        
-      }
-*/
-    }
-    awe_mesh_object.prototype = Object.create(awe_object.prototype);
-    awe_mesh_object.prototype.constructor = awe_mesh_object;
-
-    
-    
-    Object.defineProperty(awe_mesh_object.prototype, 'position', { get: function() { 
-      var mesh = this.get_mesh('position');
-      return _extend({x:0,y:0,z:0}, {
-        x: parseFloat(mesh.position.x),
-        y: parseFloat(mesh.position.y),
-        z: parseFloat(mesh.position.z),
-      });
-    } });
-    
-    Object.defineProperty(awe_mesh_object.prototype, 'rotation', { get: function() { 
-      var mesh = this.get_mesh('rotation');
-      return _extend({x:0,y:0,z:0}, {
-        x: THREE.Math.radToDeg(mesh.rotation.x),
-        y: THREE.Math.radToDeg(mesh.rotation.y),
-        z: THREE.Math.radToDeg(mesh.rotation.z),
-      });
-    } });
-    
-    Object.defineProperty(awe_mesh_object.prototype, 'scale', { get: function() { 
-      var mesh = this.get_mesh('scale');
-      return _extend({x:1,y:1,z:1}, {
-        x: parseFloat(mesh.scale.x),
-        y: parseFloat(mesh.scale.y),
-        z: parseFloat(mesh.scale.z),
-      });
-    } });
-    
-    Object.defineProperty(awe_mesh_object.prototype, 'visible', { get: function() { 
-      var mesh;
-      if (this.get_component) {
-        mesh = this.get_component('the_mesh');
-      }
-      if (!mesh) {
-        mesh = this.get_mesh('object');
-      }
-      return mesh ? +mesh.visible : 0; // output as number
-    } });
-    
-    Object.defineProperty(awe_mesh_object.prototype, 'opacity', { get: function() { 
-      var mesh;
-      if (this.get_component) {
-        mesh = this.get_component('the_mesh');
-      }
-      if (!mesh) {
-        mesh = this.get_mesh('object');
-      }
-      var opacity = 1;
-      if (mesh) {
-        mesh.traverse(function(o){
-          if (o.material && o.material.transparent) {
-            opacity = o.material.opacity;
-          }
-        })
-      }
-      return opacity
-    } });
-    
-  ;['title', 'name', 'cast_shadow', 'receive_shadow'].forEach(function(prop){
-    Object.defineProperty(awe_mesh_object.prototype, prop, { get: function() { 
-      var data = this.get_data();
-      return data[prop];
-    } });
-  });
-    
-    awe_mesh_object.prototype.move_to = function(position, animation){
-      // validate & sanitise position
-      position = _valid_coordinates(position);
-      if (position) {
-        this.update({
-          animation: animation,
-          position: position
-        });
-      }
-    };
-
-    awe_mesh_object.prototype._values_updated = function(){
-      awe_object.prototype._values_updated.call(this);
-      var mesh = this.get_mesh();
-
-      if (mesh) {
-        if (!mesh.visible) {
-          this.pause_video_texture();
-        }
-        else if (this.autoplay_texture()) {
-          this.play_video_texture();
-        }
-      }
-      
-    }
-    
-
-    awe_mesh_object.prototype.get_mesh = function(){
-      return this._get_data_value('mesh');
-    };
-    
-    awe_mesh_object.prototype.material_data = function(){
-      if (!arguments.length) {
-        return this._get_data_value('material');
-      }
-      else {
-        var m = arguments[0];
-        if (m.constructor.name == 'awe_material') {
-          m = m.value();
-        }
-        var mesh = this.get_mesh();
-        mesh.material = m;
-        this._set_data_value('material', m);        
-      }
-    };
-
-    awe_mesh_object.prototype.texture_data = function(){
-      if (!arguments.length) {
-        return this._get_data_value('texture');
-      }
-      else {
-        var t = arguments[0];
-        if (t.constructor.name == 'awe_texture') {
-          this._set_data_value('texture', t.value());
-        }
-        else {
-          this._set_data_value('texture', t);
-        }
-      }
-    };
-
-    awe_mesh_object.prototype.texture = function(){
-      var t = this.texture_data();
-      if (t && t.id) {
-        return awe.textures.view(t.id);
-      }
-    };
-    awe_mesh_object.prototype.material = function(){
-      var t = this.material_data();
-      if (t && t.id) {
-        return awe.materials.view(t.id);
-      }
-    };
-    awe_mesh_object.prototype.three_texture = function(){
-      var mesh = this._get_data_value('mesh');
-      var texture;
-      try {
-        texture = mesh.material.map;
-      }
-      catch(e) {}
-      return texture;
-    };
-    awe_mesh_object.prototype.three_material = function(){
-      var mesh = this._get_data_value('mesh');
-      var material;
-      try {
-        material = mesh.material;
-      }
-      catch(e) {}
-      return material;
-    };
-    
-    awe_mesh_object.prototype.autoplay_texture = function(){
-      var autoplay = false;
-      var texture = this.texture();
-      if (texture && texture.is_video_texture()) {
-        autoplay = texture.autoplay();
-      }
-      return autoplay;
-    };
-    awe_mesh_object.prototype.toggleplay_video_texture = function(){
-      try {
-        var awe_texture = this.texture();
-        if (awe_texture && awe_texture.is_video_texture()) {
-          console.log('texture', awe_texture, awe_texture.paused, awe_texture.texture.video, awe_texture.texture.video.paused)
-          if (awe_texture.paused) {
-            awe_texture.play();
-          }
-          else {
-            awe_texture.pause();
-          }
-        }
-      }
-      catch(e){ console.error('toggle play',e);}
-    };
-    awe_mesh_object.prototype.play_video_texture = function(){
-      var texture = this.texture();
-      if (texture && texture.is_video_texture()) {
-        texture.play();
-      }
-    };
-    awe_mesh_object.prototype.pause_video_texture = function(){
-      var texture = this.texture();
-      if (texture && texture.is_video_texture()) {
-        texture.pause();
-      }
-    };
-    awe_mesh_object.prototype.stop_video_texture = function(){
-      var texture = this.texture();
-      if (texture && texture.is_video_texture()) {
-        texture.stop();
-      }
-    };
-    awe_mesh_object.prototype.get_world_position = function(){
-      var mesh = this.get_mesh('position');
-      var pos = mesh.getWorldPosition();
-      return {x: pos.x, y: pos.y, z: pos.z};
-    };
-    awe_mesh_object.prototype.get_screen_coordinates = function(){
-      if (!awe.pov()) {
-        return;
-      }
-      var camera = awe.pov().get_mesh('position');
-      var mesh = this.get_mesh();
-      
-      if (!mesh.geometry) {
-        console.info('Screen coordinates unavailable for objects without geometries');
-        return;
-      }
-      
-      
-      // every time the camera or objects change position (or every frame)
-      camera.updateMatrixWorld(); // make sure the camera matrix is updated
-      camera.matrixWorldInverse.getInverse( camera.matrixWorld );
-      cameraViewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
-      frustum.setFromMatrix( cameraViewProjectionMatrix );
-      
-      // frustum is now ready to check all the objects you need
-      if( frustum.intersectsObject( mesh ) ) {
-        var width = canvas.clientWidth, height = canvas.clientHeight;
-        var widthHalf = width / 2, heightHalf = height / 2;
-        
-        var vector = new THREE.Vector3();
-        var projector = new THREE.Projector();
-        vector.setFromMatrixPosition( mesh.matrixWorld );
-        vector.project( camera );
-        
-        vector.x = ( vector.x * widthHalf ) + widthHalf;
-        vector.y = - ( vector.y * heightHalf ) + heightHalf;
-        return { x: vector.x, y: vector.y};
-      
-      }
-      return null;
-    };
-    awe_mesh_object.prototype._remove_child = function(child){
-      try {
-        var my_mesh = this.get_mesh();
-        var child_mesh = child.get_mesh();
-        my_mesh.remove(child_mesh);
-      }
-      catch(e) {
-        console.warn('removing mesh failed', e, this, child);
-      }
-      this_awe.scene_needs_rendering = 1;
-      
-      var object_type;
-      if (child instanceof awe_projection) {
-        object_type = 'projection';
-      }
-      else if (child instanceof awe_poi) {
-        object_type = 'poi';
-      }
-      else if (child instanceof awe_light) {
-        object_type = 'light';
-      }
-      else if (child instanceof awe_pov) {
-        object_type = 'pov';
-      }
-      else if (child instanceof THREE.Object3D) {
-        console.warn('child', child, 'not stored in .children')
-        return;
-      }
-      if (!object_type) {
-        throw 'unknown object type '+child.toString()+' '+JSON.stringify(child);
-      }
-      
-      var temp = this.children.filter(function(item){
-        return (item.object_type != object_type || item.object_id+'' != child.id+'');
-      });
-      this.children = temp;
-    };
-    awe_mesh_object.prototype._add_child = function(child){
-      var my_mesh = this.get_mesh('object');
-      var new_mesh = child instanceof THREE.Object3D ? child : child.get_mesh();
-      my_mesh.add(new_mesh);
-      this_awe.scene_needs_rendering = 1;
-      
-      var object_type;
-      if (child instanceof awe_projection) {
-        object_type = 'projection';
-      }
-      else if (child instanceof awe_poi) {
-        object_type = 'poi';
-      }
-      else if (child instanceof awe_light) {
-        object_type = 'light';
-      }
-      else if (child instanceof awe_pov) {
-        object_type = 'pov';
-      }
-      else if (child instanceof THREE.Object3D) {
-        console.warn('child', child, 'not stored in .children')
-        return;
-      }
-      if (!object_type) {
-        throw 'unknown object type '+child.toString()+' '+JSON.stringify(child);
-      }
-            
-      this.children.push({ object_type: object_type, object_id: child.id });
-      
-    };
-    awe_mesh_object.prototype.parent = function(){
-      var parent = this._get_data_value('parent');
-      if (!parent) {
-        return awe.scene();
-      }
-      switch (parent.object_type) {
-        case 'poi':
-        case 'pov':
-        case 'light':
-        case 'projection':
-          return awe[parent.object_type+'s'].view(parent.object_id);
-          break;
-        default:
-          return awe.scene();
-      }
-    };
-    awe_mesh_object.prototype.rotate = function(rotate, animation){
-      this.update({
-        rotate: rotate,
-        animation: animation
-      });
-    };
-    awe_mesh_object.prototype.position = function(position, animation){
-      this.update({
-        position: position,
-        animation: animation
-      });
-    };
-    awe_mesh_object.prototype.scale = function(scale, animation){
-      this.update({
-        scale: scale,
-        animation: animation
-      });
-    };
-    awe_mesh_object.prototype.face_user = function(){
-      
-      return this.look_at(awe.pov().get_world_position());
-      
-	  };
-
-    awe_mesh_object.prototype.look_at = function(world_coords){
-      var m1 = new THREE.Matrix4();
-      var mesh = this.get_mesh('rotation');
-      var v_target = _make_three_vector(this.get_world_position());
-      var v_eye = _make_three_vector(world_coords);
-  		
-  		_look_at.apply(m1, [v_eye, v_target, mesh.up]);
-  		mesh.quaternion.setFromRotationMatrix( m1 );
-//       TODO - test if this can be removed (it should be covered by getters)
-      this._values_updated(); 
-      awe.scene_needs_rendering = true;
-	  };
-
-    this_awe.awe_mesh_object = awe_mesh_object
-    
-    
-    // awe_poi class
-    function awe_poi(data, datastore){
-      awe_mesh_object.call(this, data, datastore);
-      
-      var scale = data.scale || { x: 1, y: 1, z: 1 };
-      var position = data.position || { x: 0, y: 0, z: 0 };
-      var rotation = data.rotation || { x: 0, y: 0, z: 0 };
-      
-      var origin = new THREE.Object3D();
-      origin.scale.set(scale.x, scale.y, scale.z)
-      origin.position.set(position.x, position.y, position.z)
-      origin.rotation.x = THREE.Math.degToRad(rotation.x);
-      origin.rotation.y = THREE.Math.degToRad(rotation.y);
-      origin.rotation.z = THREE.Math.degToRad(rotation.z);
-      origin.poi_id = this.id;
-      
-      this._set_data_value('origin', origin);
-      
-      this.scale = scale;
-      this.position = position;
-      this.rotation = rotation;
-            
-    }
-    awe_poi.prototype = Object.create(awe_mesh_object.prototype);
-    awe_poi.prototype.constructor = awe_poi;
-    
-    awe_poi.prototype.get_origin = function(){
-      return this._get_data_value('origin');
-    };
-    awe_poi.prototype.get_mesh = function(){
-      return this.get_origin();
-    };
-    
-    // awe_pov class
-    function awe_pov(data, datastore){
-      awe_mesh_object.call(this, data, datastore);
-      this.init();
-    }
-    awe_pov.prototype = Object.create(awe_mesh_object.prototype);
-    awe_pov.prototype.constructor = awe_pov;
-    awe_pov.prototype.init = function(){};
-    awe_pov.prototype.look_at_poi = function(poi_id){
-      var poi = awe.pois.view(poi_id);
-      var mesh = poi.get_mesh('position');
-      var vector = new THREE.Vector3();
-      vector.setFromMatrixPosition( mesh.matrixWorld );
-      return this.look_at(vector);
-    };
-    
-    
-
-
-    awe_pov.prototype.look_at_projection = function(projection_id){
-      var projection = awe.projections.view(projection_id);
-      var mesh = projection.get_mesh('position');
-      var vector = new THREE.Vector3();
-      vector.setFromMatrixPosition( mesh.matrixWorld );
-      return this.look_at(vector);
-    };
-    awe_pov.prototype.look_at = function(target){
-      if (!target) { return; }
-      // target can be any awe_mesh_object (poi, projection, pov), or any js object with x,y,z coordinates
-      var target_coordinates;
-      
-      switch (target.constructor.name) {
-        case 'awe_poi':
-        case 'awe_pov': 
-        case 'awe_projection':
-          target_coordinates = _valid_coordinates(target.position);
-          break;
-        default: 
-          // just check if there's an target.x target.y and target.z and we're good to go.
-          target_coordinates = _valid_coordinates(target);
-      }
-      if (target_coordinates) {
-        var mesh = this.get_mesh('rotation');
-        var vector = new THREE.Vector3(target_coordinates.x, target_coordinates.y, target_coordinates.z);
-        _look_at.call(mesh, vector);
-
-        _map_audio_listener_to_pov();
-        this_awe.scene_needs_rendering = 1;
-      }
-      return target_coordinates;
-    };
-    awe_pov.prototype.set_aspect = function(aspect){
-      var mesh = this.get_mesh();
-      mesh.aspect = aspect;
-    };
-    awe_pov.prototype.update_projection_matrix = function(){
-      var mesh = this.get_mesh();
-      mesh.updateProjectionMatrix();
-    };
-    awe_pov.prototype.set_projection_matrix = function(matrix){
-      var mesh = this.get_mesh();
-      mesh.projectionMatrix.fromArray(matrix);
-    };
-    awe_pov.prototype.get_projection_matrix = function(){
-      var mesh = this.get_mesh();
-      return mesh.projectionMatrix;
-    };
-    awe_pov.prototype.update_properties = function(){
-      console.trace('awe_pov.prototype.update_properties(): DEPRECATED')
-    };
-    
-    ;['far', 'near', 'fov', 'aspect'].forEach(function(prop){
-      Object.defineProperty(awe_pov.prototype, prop, { get: function() { 
-        var mesh = this.get_mesh();
-        return mesh[prop];
-      } });
-    });
-    
-    
-    Object.defineProperty(awe_pov.prototype, 'active', { get: function() { 
-      return this._get_data_value('active');
-    } });
-
-    
-    
-    // awe_projection class
-    function awe_projection(data, datastore){
-      awe_mesh_object.call(this, data, datastore);
-      this.init();
-      this.trigger_state(awe.OBJECT_STATES.INITIAL);
-    }
-    awe_projection.prototype = Object.create(awe_mesh_object.prototype);
-    awe_projection.prototype.constructor = awe_projection;
-    
-    
-    awe_projection.prototype.is_origin = function(){
-      console.trace('DEPRECATED: awe_projection.prototype.is_origin');
-      return false; // !!this._get_data_value('is_origin');
-    };
-
-    awe_projection.prototype.place_mesh = function(mesh){
-      var wrapper = this.get_mesh('object');
-      mesh.name = 'the_mesh';
-      wrapper.add(mesh);
-      
-//       console.log('after placing', wrapper.children.length, mesh)
-      var event = new CustomEvent('placed_mesh', { detail: { id: this.id, l: wrapper.children.length } });
-      window.dispatchEvent(event);
-      try {
-        console.log('PLACED MESH', this.id, this.get_mesh('object').children[0].geometry.boundingBox.size);
-      } catch(e) { }
-    };
-
-    awe_projection.prototype.get_component = function(name){
-      var wrapper = this.get_mesh('wrapper')
-      if (!wrapper) {
-        console.trace('no mesh!!!')
-        var position_mesh = this.get_mesh('position');
-        var rotation_mesh = this.get_mesh('rotation');
-        var scale_mesh = this.get_mesh('scale');
-    
-        console.log('no mesh',this.get_mesh(), this, position_mesh, rotation_mesh, scale_mesh)
-        return null;
-      }
-      return wrapper.getObjectByName(name);
-    };
-      
-    awe_projection.prototype.get_scale_mesh = function(){
-      return this.get_mesh('scale');
-    };
-    awe_projection.prototype.get_position_mesh = function(){
-      return this.get_mesh('position');
-    };
-    awe_projection.prototype.get_rotation_mesh = function(){
-      return this.get_mesh('rotation');
-    };
-    
-    awe_projection.prototype.get_object_mesh = function(){
-      return this.get_mesh('object');
-    };
-    awe_projection.prototype.get_three_mesh = function(){
-      return this.get_component('the_mesh');
-    };
-    
-    awe_projection.prototype.trigger_state = function(state){
-      this.state = state;
-    };
-    awe_projection.prototype.init = function(){
-      var data = this.get_data();
-      var three_mesh = data.mesh;
-      
-      var parent = this.parent();
-      
-      var wrapper = new THREE.Object3D();
-      wrapper.name = 'wrapper';
-      wrapper.projection_id = this.id;
-      
-      if (three_mesh) { // place object straight away
-        three_mesh.name = 'the_mesh';
-        wrapper.add(three_mesh);
-      }
-      
-      this.get_mesh = function(type){
-        if (!type) {
-          return wrapper;
-        }
-        switch(type) {
-          case 'wrapper':
-          case 'position':
-          case 'rotation':
-          case 'scale':
-          case 'object':
-            return wrapper;
-          case 'three':
-            return this.get_component('the_mesh');
-          default: 
-            return awe_mesh_object.prototype.get_mesh.call(this);
-        }
-      };
-      
-      if (parent && parent._add_child && typeof (parent._add_child) == 'function') {
-        // can be any awe_mesh_object
-        parent._add_child(this);
-      }
-      
-      if (!this._get_data_value('not_clickable')) {
-        _clickable_objects['projection-'+this.id] = wrapper;
-      }
-      
-
-    };
-
-    awe_projection.prototype.is_clickable = function(){
-      return !!_clickable_objects['projection-'+this.id];
-    };
-    
-    
-    
-    // awe_light class
-    function awe_light(data, datastore){
-      awe_mesh_object.call(this, data, datastore);
-    }
-    awe_light.prototype = Object.create(awe_mesh_object.prototype);
-    awe_light.prototype.constructor = awe_light;
-    
-    
-    
-    
-    
-    this_awe.constructor.prototype.renderers = new awe_v8();
-    this_awe.constructor.prototype.renderers._item_constructor = awe_renderer;
-    this_awe.constructor.prototype.renderers.add = function(BODY, HEAD) {
-      if (!BODY) { BODY = {}; }
-      if (!HEAD) { HEAD = {}; }
-      
-      // read settings
-      var settings = this_awe.util.get_settings('renderer|debug|fps|antialias|clear_color|opacity|shadows|shadow_map_type|canvas_style|container_id');
-      var capabilities = this_awe.util.get_capabilities('webgl');
-      var renderer;
-      
-      if (settings.renderer) {
-        if (capabilities.webgl && settings.renderer == 'webgl') {
-          var antialias = settings.antialias || true;
-          var three_renderer = new THREE.WebGLRenderer({ antialias: antialias, alpha: true });
-          if (!three_renderer) {
-            throw { code: 500, message: 'three.js renderer creation failed' };
-            return;
-          }
-          
-          BODY.three_renderer = three_renderer;
-          renderer = new awe_renderer(BODY, this);
-          
-          var clear_color = settings.clear_color || 0x000000;
-          var opacity = settings.opacity || 0;
-          renderer.set_clear_color( clear_color, opacity );
-          
-          // spotlight is required to add shadows!
-          // see https://github.com/mrdoob/three.js/issues/748
-          if (settings.shadows) {
-            var shadow_map_type = settings.shadow_map_type || "pcf_soft";
-            renderer.set_shadow_map_type(shadow_map_type);
-          }
-        }
-        
-        var l = this.constructor.prototype.list().length;
-        var awe_canvas = renderer.get_canvas();
-        awe_canvas.id = 'awe_canvas-'+l;
-        var style_settings = settings.canvas_style
-        if (style_settings) {
-          try {
-            for (var i in style_settings) {
-              if (style_settings.hasOwnProperty(i)) {
-                awe_canvas.style[i] = style_settings[i];                
-              }
-            }
-          }
-          catch(e) { /* TODO */ };
-        }
-        else {             
-          awe_canvas.style.position = 'absolute';
-          awe_canvas.style.top = '0px';
-          awe_canvas.style.left = '0px';
-          awe_canvas.style.width = '100%';
-          awe_canvas.style.height = '100%';
-        }
-        if (BODY.container_id && document.getElementById(BODY.container_id)) {
-          document.getElementById(BODY.container_id).appendChild(awe_canvas);
-        }
-        else if (settings.container_id && document.getElementById(settings.container_id)) {
-          document.getElementById(settings.container_id).appendChild(awe_canvas);
-        }
-        else {
-          document.body.appendChild(awe_canvas);
-        }
-        var w = awe_canvas.parentNode.clientWidth,
-          h = awe_canvas.parentNode.clientHeight;
-          
-        if (!w || !h) {
-          console.info('awe canvas container has no height - making it use window dimensions', w, h);
-          w = window.innerWidth;
-          h = window.innerHeight;
-        }
-        renderer.set_size(w, h, false);
-        
-      }
-      else {
-        throw { code: 500, message: 'three.js renderer not defined' };
-      }
-      
-      this_awe.scene_needs_rendering = 1;
-      return this.constructor.prototype.add.call(this, renderer, HEAD); // super
-    }
-
-    this_awe.constructor.prototype.renderer = function(id) {
-      return this_awe.renderers.view({ id: id ? id : 'default' });
-    }; 
-
-    this_awe.constructor.prototype.lights = new awe_v8();
-    this_awe.constructor.prototype.lights._item_constructor = awe_light;
-    this_awe.constructor.prototype.lights.add = function(BODY, HEAD) {
-      if (!BODY) { BODY = {}; }
-      if (!HEAD) { HEAD = {}; }
-      if (!Array.isArray(BODY)) {
-        BODY = [BODY];
-      }
-      var results = [],
-        self = this;
-        
-      BODY.forEach(function(BODY_item){
-          
-        // sensible defaults
-        BODY_item.id = BODY_item.id || "light-"+random_id();
-        BODY_item.visible = BODY_item.visible !== undefined ? BODY_item.visible : 1;
-        BODY_item.type = BODY_item.type !== undefined ? BODY_item.type : 'hemisphere';
-        BODY_item.color = BODY_item.color !== undefined ? BODY_item.color : 0x404040;
-  
-        if (HEAD.parent && HEAD.parent.object_id && HEAD.parent.object_type && this_awe[HEAD.parent.object_type+'s'] && ''+this_awe[HEAD.parent.object_type+'s'] == 'awe_v8_object')  {
-          try {
-            BODY_item.parent = HEAD.parent;
-          }
-          catch(e) {
-            consoe.log(e)
-            this_awe.error_handler(e);
-          }
-        }
-
-        var three_light, 
-          position = true,
-          shadows = false;
-        switch (BODY_item.type) {
-          case 'area':
-            three_light = new THREE.AreaLight(BODY_item.color);
-            if (parseInt(BODY_item.intensity) && parseInt(BODY_item.intensity) != NaN) {
-              three_light.intensity = parseInt(BODY_item.intensity);
-            }
-            break;
-          case 'directional':
-            three_light = new THREE.DirectionalLight(BODY_item.color);
-            shadows = true;
-            if (parseInt(BODY_item.intensity) && parseInt(BODY_item.intensity) != NaN) {
-              three_light.intensity = parseInt(BODY_item.intensity);
-            }
-            break;
-          case 'hemisphere':
-            var ground_color;
-            if (BODY_item.ground_color) {
-              ground_color = BODY_item.ground_color;
-            }
-            three_light = new THREE.HemisphereLight(BODY_item.color, ground_color);
-            position = false;
-            if (parseInt(BODY_item.intensity) && parseInt(BODY_item.intensity) != NaN) {
-              three_light.intensity = parseInt(BODY_item.intensity);
-            }
-            break;
-          case 'point':
-            three_light = new THREE.PointLight(BODY_item.color);
-            if (parseInt(BODY_item.distance) != NaN) {
-              three_light.distance = parseInt(BODY_item.distance);
-            }
-            if (parseInt(BODY_item.decay) != NaN) {
-              three_light.decay = parseInt(BODY_item.decay);
-            }
-            if (parseInt(BODY_item.intensity) && parseInt(BODY_item.intensity) != NaN) {
-              three_light.intensity = parseInt(BODY_item.intensity);
-            }
-            break;
-          case 'spot':
-            three_light = new THREE.SpotLight(BODY_item.color);
-            if (parseFloat(BODY_item.angle) && parseFloat(BODY_item.angle) != NaN) {
-              three_light.angle = parseFloat(BODY_item.angle);
-            }
-            if (parseInt(BODY_item.distance) && parseInt(BODY_item.distance) != NaN) {
-              three_light.distance = parseInt(BODY_item.distance);
-            }
-            if (parseInt(BODY_item.decay) && parseInt(BODY_item.decay) != NaN) {
-              three_light.decay = parseInt(BODY_item.decay);
-            }
-            if (parseFloat(BODY_item.exponent) && parseFloat(BODY_item.exponent) != NaN) {
-              three_light.exponent = parseFloat(BODY_item.exponent);
-            }
-            if (parseInt(BODY_item.intensity) && parseInt(BODY_item.intensity) != NaN) {
-              three_light.intensity = parseInt(BODY_item.intensity);
-            }
-            shadows = true;
-
-            break;
-          default: 
-            three_light = new THREE.AmbientLight(BODY_item.color);
-        }
-        
-        // spot and directional lights
-        if (shadows && three_light.shadow) {
-          
-          if (undefined !== BODY_item.only_shadow) {
-            three_light.onlyShadow = !!BODY_item.only_shadow;
-          }
-          if (undefined !== BODY_item.cast_shadow) {
-            three_light.castShadow = !!BODY_item.cast_shadow;
-          }
-          if (undefined !== BODY_item.shadow_camera_visible) {
-            three_light.shadow.camera.visible = !!BODY_item.shadow_camera_visible;
-            three_light.shadow.camera.near = BODY_item.shadow_camera_near || 0.01;
-            three_light.shadow.camera.far = BODY_item.shadow_camera_far || 5000;
-          }    
-
-        
-          if (parseInt(BODY_item.shadow_bias) != NaN) {
-            three_light.shadow.bias = parseInt(BODY_item.shadow_bias);
-          }
-          if (three_light.shadow.map) {
-            if (parseInt(BODY_item.shadow_map_width) != NaN) {
-              three_light.shadow.map.width = parseInt(BODY_item.shadow_map_width);
-            }
-            if (parseInt(BODY_item.shadow_map_height) != NaN) {
-              three_light.shadow.map.height = parseInt(BODY_item.shadow_map_height);
-            }
-          }
-        }
-
-        if (three_light.target && three_light.target.position && BODY_item.target && typeof(BODY_item.target) == 'object') {
-          three_light.target.position.set(BODY_item.target.x || 0, BODY_item.target.y || 0, BODY_item.target.z || 0)
-        }
-        
-        if (position && three_light.position && BODY_item.position && typeof(BODY_item.position) == 'object') {
-          three_light.position.set(BODY_item.position.x || 0, BODY_item.position.y || 0, BODY_item.position.z || 0)
-        
-        }
-        
-        BODY_item.mesh = three_light;
-        var light = new awe_light(BODY_item, self);
-        
-        var parent = light.parent();
-        if (parent && parent._add_child && typeof (parent._add_child) == 'function') {
-          // can be any awe_mesh_object
-          parent._add_child(light);
-          if (three_light.target) {
-            parent._add_child(three_light.target);
-          }
-        }
-        
-        this_awe.scene_needs_rendering = 1;
-        results.push(light);
-      });
-      var ret = this.constructor.prototype.add.call(this, results, HEAD); // super
-      _update_materials();
-      return ret;
-    }
-    this_awe.constructor.prototype.lights.update = function(BODY, HEAD) {
-      if (!BODY) { BODY = {}; }
-      if (!HEAD) { HEAD = {}; }
-      if (!Array.isArray(BODY)) {
-        BODY = [BODY];
-      }
-      var return_result = {},
-        self = this;
-      
-      BODY.forEach(function(item){
-        if (item.data && item.where && item.where.id) {
-          var fields_updated = [];
-          if (item.data.position) { fields_updated.push('position'); }
-          if (item.data.scale) { fields_updated.push('scale'); }
-          if (item.data.rotation) { fields_updated.push('rotation'); }
-          if (item.data.target) { fields_updated.push('target'); }
-          if (fields_updated.length) {
-            HEAD.fields_updated = fields_updated;
-          }
-          if (!Array.isArray(item.where.id)) {
-            item.where.id = [item.where.id];
-          }
-          item.where.id.forEach(function(where_id){
-            try {
-              var object = this_awe.lights.view(where_id);
-              var mesh = object.get_mesh();
-            } catch(e) { return; /* TODO */ };
-            if(item.data.animation && parseFloat(item.data.animation.duration) > 0) {
-              // after tween ends _update_materials();
-              try {
-                _tween(_extend({
-                  object: object,
-//                   mesh: mesh,
-                  end_state: item.data
-                }, item.data.animation));
-              } catch(e) { /* TODO */ };
-            }
-            else {
-              try {
-                var mesh = _update_mesh_io(item.data, mesh);
-              } catch(e) { /* TODO */ };
-            }
-            var result = _clone(item);
-            result.mesh = mesh;
-            
-            return_result[where_id] = self.constructor.prototype.update.call(self, result, HEAD); // super
-          });
-        }
-      });
-      _update_materials();
-      return return_result;
-    };
-    this_awe.constructor.prototype.lights.delete = function(BODY, HEAD) {
-      if (!BODY) { BODY = {}; }
-      if (!HEAD) { HEAD = {}; }
-      var id_array = [];
-      if (BODY.id !== undefined) {
-        id_array = Array.isArray(BODY.id) ? BODY.id : [BODY.id];
-      }
-      else if (typeof BODY == 'string' || typeof BODY == 'number') {
-        id_array = [BODY];
-      }
-      else if (Array.isArray(BODY)) {
-        id_array = BODY;
-      }
-      
-      id_array.forEach(function(BODY_item){
-        var light;
-        if (typeof BODY_item == 'string' || typeof BODY_item == 'number') {
-          light = this_awe.lights.view(BODY_item);
-          BODY_item = { id: BODY_item };
-        }
-        else if (BODY_item.id) {
-          light = this_awe.lights.view(BODY_item.id);
-        }
-        
-        
-        if (!light) {
-          console.trace('cant delete',BODY_item);
-          return;
-        }
-        var mesh = light.get_mesh();
-        if (mesh && mesh.parent) {
-          if (mesh.target) { 
-            mesh.parent.remove(mesh.target);
-          }
-          mesh.parent.remove(mesh);
-        }
-        else {
-          console.log('no light mesh to delete!', BODY, HEAD)
-        } 
-      });
-      
-      this_awe.scene_needs_rendering = 1;
-      return this.constructor.prototype.delete.call(this, BODY, HEAD); // super
-    };
-    
-    this_awe.constructor.prototype.video_streams = new awe_v8();
-    this_awe.constructor.prototype.video_streams._item_constructor = awe_video_stream;
-    this_awe.constructor.prototype.video_streams.add = function(BODY, HEAD) {
-      var capabilities = this_awe.util.get_capabilities('gum');
-      if (capabilities.gum) {
-        if (!BODY) { BODY = {}; }
-        if (!HEAD) { HEAD = {}; }
-        try {
-          var self = this,
-            video_id = 'video_stream-'+BODY.id+'-'+random_id(),
-            video = document.createElement('video');
-          
-          video.setAttribute('id', video_id);
-          video.setAttribute('autoplay', true);
-          video.style.position = 'absolute';
-          video.style.top = '-999em';
-          video.style.left = '-999em';
-          video.style.height = '100%';
-          video.style.width = '100%';
-          video.setAttribute('width', '100%');  
-          video.setAttribute('height', '100%');
-          
-          BODY.video_element = video;
-          var video_stream = new awe_video_stream(BODY, this);
-          var result = this.constructor.prototype.add.call(this, video_stream, HEAD); // super
-          // if many sources try to get the environemt-facing camera
-          
-          var go = function(video_source_id){
-            var options = this_awe.util.extend({
-              video: true
-            }, BODY.gum_options);
-            if (video_source_id) {
-              options.video = {
-                optional: [{ facingMode: (BODY.facing_mode ? BODY.facing_mode : "environment") }, {sourceId: video_source_id}]
-              };
-            }
-            // clear before each access request
-            this_awe.gum_denied = false;                console.log('requesting gum')
-            this_awe.util.get_user_media(options, 
-              function(stream) {
-                document.body.appendChild(video);
-                video.muted = true;
-                
-                BODY.stream = stream;
-                self.constructor.prototype.update.call(this, {data: {stream: stream}, where: {id: BODY.id}}, HEAD); // super
-                this_awe.util.connect_stream_to_src(stream, video);
-                var targets = this_awe.util.get_stream_targets();
-                
-                video.addEventListener('pause', function(){
-                  var event = new CustomEvent('gum_pause', { detail: { id: BODY.id } });
-                  window.dispatchEvent(event);
-                });
-
-                if (video.readyState == video.HAVE_METADATA) {
-                  var event = new CustomEvent('gum_ready', { detail: { id: BODY.id } });
-                  window.dispatchEvent(event);
-                }
-                else {
-                  video.addEventListener('loadedmetadata', function (e) {
-                    var event = new CustomEvent('gum_ready', { detail: { id: BODY.id } });
-                    window.dispatchEvent(event);
-                  }, false);
-                }
-              }, 
-              function(e) {
-                this_awe.gum_denied = true;
-                var event = new CustomEvent('gum_error', { detail: { id: BODY.id } });
-                window.dispatchEvent(event);
-              }
-            );
-          }
-          
-          if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {
-            navigator.mediaDevices.enumerateDevices()
-            .then(function(devices) {
-              var selected_source = null;
-              var last_videoinput_source = null;
-              devices.forEach(function(device) {
-                if (device.kind === 'videoinput') {
-                  if (BODY.facing_mode === 'environment' && device.label.indexOf('back') !== -1) {
-                    selected_source = device.deviceId;
-                  }
-                  last_videoinput_source = device.deviceId;
-                }
-              });
-              if ((!selected_source || BODY.facing_mode === 'environment') && last_videoinput_source) {
-                selected_source = last_videoinput_source;
-              }
-              go(selected_source);
-            })
-            .catch(function(err) {
-              console.log(err.name + ": " + err.message);
-            });
-          }
-          else if (window.MediaStreamTrack && window.MediaStreamTrack.getSources) {
-            MediaStreamTrack.getSources(function(source_infos) {
-              var selected_source = null;
-              for (var i = 0; i != source_infos.length; ++i) {
-                var source_info = source_infos[i];
-                if (source_info.kind === 'video') {
-                  if (!selected_source || (source_info.facing && source_info.facing == (BODY.facing_mode ? BODY.facing_mode : "environment") )) {
-                    selected_source = source_info.id;
-                  }
-                }
-              }
-              go(selected_source);
-            });
-          }
-          else {
-            go();
-          }
-        }
-        catch(e) {
-          console.log(e);
-        }
-        return result;
-      }
-      else {
-        // throw { code: 500, message: 'video streams not supported by this browser' };
-      }
-    };
-    this_awe.constructor.prototype.video_streams.delete = function(BODY, HEAD) {
-      var capabilities = this_awe.util.get_capabilities('gum');
-      if (capabilities.gum) {
-        if (!BODY) { BODY = {}; }
-        if (!HEAD) { HEAD = {}; }
-        try {
-          if (typeof BODY == 'string' || typeof BODY == 'number') {
-            video_stream = this.constructor.prototype.view(BODY);
-            BODY = { id: BODY };
-          }
-          else if (BODY.id) {
-            video_stream = this.constructor.prototype.view(BODY.id);
-          }
-          if (!video_stream) {
-            return;
-          }
-          var stream = video_stream.get_stream();
-          if (stream && stream.stop) {
-            stream.stop();
-          }
-          else {
-            try {
-              stream.getVideoTracks().forEach(function(s){
-                s.stop();
-              });
-              stream.getAudioTracks().forEach(function(s){
-                s.stop();
-              });
-            }
-            catch(e){}
-          }
-          // remove video element
-          var video = video_stream.get_video_element();
-          video.parentNode.removeChild(video);
-          
-          return this.constructor.prototype.delete.call(this, BODY, HEAD); // super
-        }
-        catch(e) {
-          console.log(e);
-        }
-      }
-    };
-
-    this_awe.constructor.prototype.video_stream = function(id) {
-      return this_awe.video_streams.view({ id: id ? id : 'default' });
-    }; 
-    
-    this_awe.constructor.prototype.scenes = new awe_v8();
-    this_awe.constructor.prototype.scenes._item_constructor = awe_scene;
-    this_awe.constructor.prototype.scenes.add = function(BODY, HEAD) {
-      if (!BODY) { BODY = {}; }
-      if (!HEAD) { HEAD = {}; }
-      
-      if (!Array.isArray(BODY)) {
-        BODY = [BODY];
-      }
-      var results = [],
-        self = this;
-        
-      BODY.forEach(function(BODY_item){
-        var scene = new THREE.Scene();
-        if (BODY_item.container_id && document.getElementById(BODY_item.container_id)) {
-          scene.element = document.getElementById(BODY_item.container_id);
-        }
-        BODY_item.three_scene = scene;
-        var item = new awe_scene(BODY_item, self);
-        results.push(item);
-        this_awe.scene_needs_rendering = 1;
-      });
-      return this.constructor.prototype.add.call(this, results, HEAD); // super
-    }
-
-    this_awe.constructor.prototype.scene = function(id) {
-      return this_awe.scenes.view({ id: id ? id : 'default' });
-    };
-    this_awe.constructor.prototype.scene.stringify = function() {
-      // TODO walk the scene and stringify to JSON
-    }
-    
-
-
-    
-    
-    this_awe.constructor.prototype.povs = new awe_v8();
-    this_awe.constructor.prototype.povs._item_constructor = awe_pov;
-    this_awe.constructor.prototype.povs.add = function(BODY, HEAD) {
-      if (!BODY) { BODY = {}; }
-      if (!HEAD) { HEAD = {}; }
-      if (!Array.isArray(BODY)){
-        BODY = [BODY];
-      }
-      var settings = this_awe.util.get_settings('fov|near|far|default_camera_position');
-      var self = this;
-      var result_ids = [];
-      
-      var fov = settings.fov || 65;  // ~fov of ios devices - TODO: should set default based on device_type or ideally camera introspection
-      var near = settings.near || 1;
-      var far = settings.far || 20000;
-      
-      var awe_canvas = this_awe.renderer().get_canvas();
-      var aspect_ratio = awe_canvas.clientWidth / awe_canvas.clientHeight; 
-      
-      BODY.forEach(function(BODY_item){
-        var camera = new THREE.PerspectiveCamera(
-          fov,
-          aspect_ratio,
-          near,
-          far
-        );
-        if (!settings.default_camera_position) {
-          this_awe.settings.add({
-            id: 'default_camera_position',
-            value: { x:0, y:0, z:0 },
-          });
-        }
-        BODY_item.mesh = camera;
-        var position = _extend({x:0, y:0, z:0}, settings.default_camera_position);
-        camera.position.set(position.x, position.y, position.z);
-        this_awe.scene().add(camera);
-        
-        var result = new awe_pov(BODY_item, self);
-        
-        this_awe.scene_needs_rendering = 1;
-        var ret = self.constructor.prototype.add.call(self, result, HEAD); // super
-        result_ids.push(ret);
-        result.look_at(this_awe.origin);
-      })
-      
-      return { id: result_ids };
-    };
-    
-    this_awe.constructor.prototype.povs.update = function(BODY, HEAD) {
-      if (!BODY) { BODY = {}; }
-      if (!HEAD) { HEAD = {}; }
-      if (!Array.isArray(BODY)) {
-        BODY = [BODY];
-      }
-      
-      var return_result = {},
-        self = this;
-        
-      BODY.forEach(function(item){
-        if (item.data && item.where && item.where.id) {
-          var fields_updated = [];
-          if (!Array.isArray(item.where.id)) {
-            item.where.id = [item.where.id];
-          }
-          if (item.data.position) {
-            fields_updated.push('position');
-            var users_step_callback;
-            if (item.data.animation && item.data.animation.step_callback) {
-              users_step_callback = item.data.animation.step_callback;
-              item.data.animation.step_callback = function(io) {
-                this_awe.util.audio_context.listener.setPosition(io.object.position.x, io.object.position.y, io.object.position.z);
-                return users_step_callback(io);
-              }
-            }
-          }
-          if (item.data.scale) { fields_updated.push('scale'); }
-          if (item.data.rotation) {
-            fields_updated.push('rotation');
-            _map_audio_listener_to_pov();
-          }
-          if (fields_updated.length) {
-            HEAD.fields_updated = fields_updated;
-          }
-          item.where.id.forEach(function(where_id){  
-            try {
-              var object = this_awe.povs.view(where_id);
-              var mesh = object.get_mesh();
-            } catch(e) { return; /* TODO */ };
-            if(item.data.animation && parseFloat(item.data.animation.duration) > 0) {
-              try {
-                _tween(_extend({
-                  object: object,
-//                   mesh: mesh,
-                  end_state: item.data
-                }, item.data.animation));
-              } catch(e) { /* TODO */ };
-            }
-            else {
-              var mesh = _update_mesh_io(item.data, mesh);
-            }
-            var result = _clone(item);
-            result.mesh = mesh;
-            return_result[where_id] = self.constructor.prototype.update.call(self, result, HEAD); // super
-          });
-          this_awe.scene_needs_rendering = 1;
-          
-        }
-      });
-      return return_result;
-    };
-
-    this_awe.constructor.prototype.pov = function(id) {
-      if (id) {
-        return this_awe.povs.view({ id: id });
-      }
-      else {
-        var povs = this_awe.povs.list({active:true});
-        if (!povs.length) {
-          povs = this_awe.povs.list({id:'default'});
-        }
-        if (!povs.length) {
-          povs = this_awe.povs.list({visible:true});
-        }
-        if (!povs.length) {
-          povs = this_awe.povs.list();
-        }
-        return povs[0];
-      }
-    };
-    
-    this_awe.constructor.prototype.pois = new awe_v8();
-    this_awe.constructor.prototype.pois._item_constructor = awe_poi;
-    this_awe.constructor.prototype.pois.add = function(BODY, HEAD) {
-      if (!BODY) { BODY = {}; }
-      if (!HEAD) { HEAD = {}; }
-      if (!Array.isArray(BODY)) {
-        BODY = [BODY];
-      }
-      var self = this,
-        pois = [];
-      
-      BODY.forEach(function(BODY_item){
-          
-        if (!BODY_item.id) {
-          BODY_item.id = 'poi-'+random_id();
-        }
-        
-        var projections = [];
-        if (BODY_item.projections && Array.isArray(BODY_item.projections)) {
-          projections = BODY_item.projections;
-          delete BODY_item.projections;
-        }
-
-        var projection_io = {};
-        var parent;
-        if (HEAD.poi_id) {
-          parent = {
-            object_type: 'poi',
-            object_id: HEAD.poi_id
-          };
-        }
-        else if (HEAD.parent) {
-          parent = HEAD.parent;
-        }
-        BODY_item.parent = parent;
-        var poi = new awe_poi(BODY_item, self);
-        pois.push(poi);
-        
-        // add the mesh to the scene/parent
-        var p = poi.parent();
-        if (p && p._add_child) {
-          p._add_child(poi)
-        }
-        else {
-          console.trace('no add_child', p, poi);
-        }
-        projections.forEach(function(projection_io){
-          if (!projection_io.id) {
-            projection_io.id = 'projection-'+random_id();
-          }
-          this_awe.projections.add(projection_io, { poi_id: BODY_item.id });
-        });
-      });
-      return this.constructor.prototype.add.call(self, pois, HEAD); // super
-    };
-    this_awe.constructor.prototype.pois.update = function(BODY, HEAD) {
-      if (!BODY) { BODY = {}; }
-      if (!HEAD) { HEAD = {}; }
-      if (!Array.isArray(BODY)) {
-        BODY = [BODY];
-      }
-      var return_result = {},
-        self = this;
-      BODY.forEach(function(item){
-        if (item.data && item.where && item.where.id) {
-          var fields_updated = [];
-          if (item.data.position) { fields_updated.push('position'); } 
-          if (item.data.scale) { fields_updated.push('scale'); } 
-          if (item.data.rotation) { fields_updated.push('rotation'); } 
-          if (fields_updated.length) {
-            HEAD.fields_updated = fields_updated;
-          }
-          if (!Array.isArray(item.where.id)) {
-            item.where.id = [item.where.id];
-          }
-          item.where.id.forEach(function(where_id){
-            try {
-              var object = this_awe.pois.view(where_id);
-              var mesh = object.get_mesh();
-            } catch(e) { return; /* TODO */ };
-            
-            if(item.data.animation && parseFloat(item.data.animation.duration) > 0) {
-              var poi = self.constructor.prototype.view(where_id),
-                end_callback = item.data.animation.end_callback;
-              item.data.animation.end_callback = function(io){
-                if (poi) {
-                  poi._values_updated();
-                }
-                if (end_callback) {
-                  end_callback(io);
-                }
-              }
-              try {
-                console.log('poi tween', item.data, item.data.animation, object);
-                _tween(_extend({
-                  object: object,
-//                   mesh: mesh,
-                  end_state: item.data,
-                }, item.data.animation));
-              } catch(e) { /* TODO */ };
-            }
-            else {
-              try {
-                var mesh = _update_mesh_io(item.data, mesh);
-                this_awe.scene_needs_rendering = 1;
-              } catch(e) { /* TODO */ };
-            }
-            var result = _clone(item);
-            result.mesh = mesh;
-            return_result[where_id] = self.constructor.prototype.update.call(self, result, HEAD); // super
-          })
-        }
-      })
-      return return_result;
-    };
-    this_awe.constructor.prototype.pois.delete = function(BODY, HEAD) {
-      if (!BODY) { BODY = {}; }
-      if (!HEAD) { HEAD = {}; }
-      var projection;
-      try {
-        if (typeof BODY == 'string' || typeof BODY == 'number') {
-          poi = this_awe.pois.view(BODY);
-          BODY = { id: BODY };
-        }
-        else if (BODY.id) {
-          poi = this_awe.pois.view(BODY.id);
-        }
-        if (poi.children) {
-          poi.children.forEach(function(item){
-            if (this_awe[item.object_type+'s']) {
-              this_awe[item.object_type+'s'].delete(item.object_id);
-            }
-          });
-        }
-        
-        if (poi.parent && typeof(poi.parent) == 'function')  {
-          try {
-            parent = poi.parent();
-            parent._remove_child(poi);
-            this_awe.scene_needs_rendering = 1;
-          }
-          catch(e) {}
-        }
-        else {
-          // remove mesh directly from parent mesh
-          var mesh = poi.get_mesh();
-          if (mesh && mesh.parent) {
-            mesh.parent.remove(mesh);
-            this_awe.scene_needs_rendering = 1;
-          }
-          else {
-            console.log('no mesh to delete!', BODY, HEAD)
-          } 
-        }
-      }
-      catch(e) {
-        this_awe.error_handler(e);  
-      }
-      this_awe.scene_needs_rendering = 1;
-      return this.constructor.prototype.delete.call(this, BODY, HEAD); // super
-    };
-
-    this_awe.constructor.prototype.projections = new awe_v8();
-    this_awe.constructor.prototype.projections._item_constructor = awe_projection;
-    this_awe.constructor.prototype.projections.list = function(BODY, HEAD) {
-      if (!BODY) { BODY = {}; }
-      if (!HEAD) { HEAD = {}; }
-      if (BODY.type && BODY.type === "clickable") {
-        var meshes = [];
-        Object.keys(_clickable_objects).forEach(function(key){
-          if (_clickable_objects[key].visible) {
-            // skip invisible meshes
-            meshes.push(_clickable_objects[key]);
-          }
-        });
-        return meshes;
-      } else {
-        return this.constructor.prototype.list.call(this, BODY, HEAD); // super
-      }
-    }
-    this_awe.constructor.prototype.projections.add = function(BODY, HEAD) {
-      if (!BODY) { BODY = {}; }
-      if (!HEAD) { HEAD = {}; }
-      if (!Array.isArray(BODY)) {
-        BODY = [BODY];
-      }
-      var result_ids = [],
-        self = this,
-        settings = this_awe.util.get_settings('loading_strategy'),
-        loading_strategy = HEAD.loading_strategy ? HEAD.loading_strategy : (settings.loading_strategy || 'preload');
-
-      function finish_add(id) {
-        var projection = this_awe.projections.view(id);
-/*
-        if (!projection) {
-          // super add() failed
-          console.warn('no projection', id)
-          return;
-        }
-*/
-/*
-        var mesh = projection.get_mesh();
-        if (!mesh) {
-          // mesh instance creation failed
-          console.warn('no mesh', id)
-          return
-        }
-        mesh.projection_id = id;
-*/
-/*
-        var parent = projection.parent();
-        if (!parent) {
-          // not origin, but has no parent to be added to
-          console.warn('no parent', id)
-          return;
-        }
-        if (!projection._get_data_value('not_clickable')) {
-          _clickable_objects['projection-'+id] = mesh;
-        }
-        
-        if (parent._add_child && typeof (parent._add_child) == 'function') {
-          // can be any awe_mesh_object
-
-          parent._add_child(projection);
-        }
-        else {
-          console.warn('parent doesnt have _add_child() method', parent);
-          return;
-        }
-*/
-        projection._values_updated();
-        this_awe.scene_needs_rendering = 1;
-        projection.loaded = true;
-        projection.trigger_state(awe.OBJECT_STATES.DEFAULT);
-        projection.trigger_state(awe.OBJECT_STATES.LOADED);
-/*
-        try {
-          console.log('LOADED', projection.id, projection.get_mesh('object').children[0].geometry.boundingBox.size);
-        } catch(e) { console.log(e); }
-*/
-        var event = new CustomEvent('projection_loaded', {detail: id});
-        window.dispatchEvent(event);
-        
-      }
-      
-      BODY.forEach(function(BODY_item){
-        var config = _clone(BODY_item);
-        var geometry, material, mesh, parent, origin;
-        if (!BODY_item.id) {
-           throw 'projections.add(): BODY.id required';
-        }
-        if (this_awe.projections.view(BODY_item.id)) {
-          console.warn('projections.add(): BODY.id already exists', BODY_item.id);
-          return;
-        }
-        
-        BODY_item.config = config;
-        if (HEAD.parent && HEAD.parent.object_id && HEAD.parent.object_type && this_awe[HEAD.parent.object_type+'s'] && ''+this_awe[HEAD.parent.object_type+'s'] == 'awe_v8_object')  {
-          try {
-            BODY_item.parent = HEAD.parent;
-          }
-          catch(e) {
-            console.log(e)
-            this_awe.error_handler(e);
-          }
-        }
-        else if (HEAD.poi_id) {
-//          parent = this_awe.pois.view(HEAD.poi_id);
-          BODY_item.parent = {
-            object_type: 'poi',
-            object_id: HEAD.poi_id
-          };
-        }
-        if (!_check_parent(BODY_item)) {
-          return null;
-        }
-        origin = new THREE.Object3D();
-        origin.name = 'projection ID:'+BODY_item.id+' origin';
-        BODY_item.origin = origin;
-        
-        /*
-if (!parent) {
-          throw 'HEAD.poi_id or HEAD.parent required';
-        }
-*/
-        
-        if (!BODY_item.material) {
-          BODY_item.material = {};
-        }
-        if (!BODY_item.texture) {
-          BODY_item.texture = {};
-        }
-        if (BODY_item.sound) {
-          var capabilities = this_awe.util.get_capabilities('audio');
-          if (capabilities.audio) {
-            if (BODY_item.sound.path == undefined) {
-              throw "sound path required";
-            }
-            BODY_item.sound.source = this_awe.util.audio_context.createBufferSource();
-            BODY_item.sound.panner = this_awe.util.audio_context.createPanner();
-            BODY_item.sound.source.connect(BODY_item.sound.panner);
-            BODY_item.sound.panner.connect(this_awe.util.audio_context.destination);
-            BODY_item.sound.panner.refDistance = 100;
-            var position = { x:0, y:0, z:0 };
-            if (BODY_item.position !== undefined) {
-              for (var p in BODY_item.position) {
-                if (BODY_item.position.hasOwnProperty(p)) {
-                  position[p] = BODY_item.position[p];
-                }
-              }
-            }
-            BODY_item.sound.panner.setPosition(position.x, position.y, position.z);
-            this_awe.sounds.add(BODY_item.sound);
-          }
-        }
-        
-        var item, item_id;
-        if (BODY_item.geometry) {
-          if (BODY_item.geometry.shape) {
-            var shape_data = _validate_shape(BODY_item.geometry);
-            switch(BODY_item.geometry.shape) {
-              case 'cube': 
-                geometry = new THREE.BoxGeometry(shape_data.x, shape_data.y, shape_data.z);
-                break;
-              case 'circle': 
-                geometry = new THREE.CircleGeometry(shape_data.radius, shape_data.segments);
-                break;
-              case 'sphere': 
-                geometry = new THREE.SphereGeometry(shape_data.radius, shape_data.widthSegments, shape_data.heightSegments, shape_data.phiStart, shape_data.phiLength, shape_data.thetaStart, shape_data.thetaLength);
-                break;
-              case 'cylinder': 
-                geometry = new THREE.CylinderGeometry(shape_data.radiusTop, shape_data.radiusBottom, shape_data.height, shape_data.radiusSegments, shape_data.heightSegments, shape_data.openEnded);
-                break;
-              case 'lathe': 
-                geometry = new THREE.LatheGeometry(shape_data.points, shape_data.segments, shape_data.phiStart, shape_data.phiLength);
-                break;
-              case 'octahedron': 
-                geometry = new THREE.OctahedronGeometry(shape_data.radius, shape_data.detail);
-                break;
-              case 'plane': 
-  //              geometry = new THREE.PlaneGeometry(shape_data.width, shape_data.height, shape_data.widthSegments, shape_data.heightSegments)
-                geometry = new THREE.PlaneBufferGeometry(parseInt(shape_data.width,10), parseInt(shape_data.height,10), parseInt(shape_data.widthSegments,10), parseInt(shape_data.heightSegments,10));
-                break;
-              case 'tetrahedron': 
-                geometry = new THREE.TetrahedronGeometry(shape_data.radius, shape_data.detail);
-                break;
-              case 'text': 
-                // async process
-                if (!shape_data.font_url) {
-                  console.warn('font_url required');
-                  throw { code: 500, message: 'font_url required for text projection'};
-                  // out of the forEach loop
-                  return;
-                }
-                item = new awe_projection(BODY_item, self);
-                item_id = self.constructor.prototype.add.call(self, item, HEAD); // super
-                item.trigger_state(awe.OBJECT_STATES.DEFAULT);
-                item.trigger_state(awe.OBJECT_STATES.LOADING);
-                
-                // load the font
-                var loader = new THREE.FontLoader();
-                loader.load( shape_data.font_url, function ( font ) {
-                  shape_data.parameters.font = font;
-                  
-          				var geometry = new THREE.TextGeometry( shape_data.text, shape_data.parameters );
-          				var texture, material;
-                  if (Object.keys(BODY_item.texture).length) {
-                    if (BODY_item.geometry.x) { // a cube
-                      BODY_item.texture.width = BODY_item.geometry.x; 
-                    }
-                    if (BODY_item.geometry.width) { // a plane
-                      BODY_item.texture.width = BODY_item.geometry.width; 
-                    }
-                    if (BODY_item.geometry.y) { // a cube
-                      BODY_item.texture.height = BODY_item.geometry.y; 
-                    }
-                    if (BODY_item.geometry.height) { // a plane
-                      BODY_item.texture.height = BODY_item.geometry.height; 
-                    }
-                      
-                    var capabilities = this_awe.util.get_capabilities('gum');
-                    if (BODY_item.texture.path == 'camerastream' && !capabilities.gum){
-                      
-                      delete(BODY_item.texture.path);
-                      BODY_item.texture.width = 800;
-                      BODY_item.texture.height = 600;
-                      BODY_item.texture.background_color = null;
-                      BODY_item.texture.label = 'camerastream texture is unsupported on this device';
-                      BODY_item.texture.font = '100px Arial';
-                    }
-                    // hidden projection textures start out as paused
-                    BODY_item.texture.paused = (BODY_item.visible != undefined ? !BODY_item.visible : false);
-                    BODY_item.texture.success_callback = function(){
-                      awe.util.trigger_event(window, 'texture_loaded', {detail: BODY_item.id});
-                    
-                    }
-                    var texture_id = this_awe.textures.add(BODY_item.texture);
-                    BODY_item.texture.id = texture_id.id;
-                    if (BODY_item.texture.color) {
-                      BODY_item.material.color = BODY_item.texture.color;
-                    }
-                    BODY_item.material.map = this_awe.textures.view(texture_id).value();
-                  }
-  
-                  var material_id = this_awe.materials.add(BODY_item.material);
-                  BODY_item.material.id = material_id.id;
-                  var material = this_awe.materials.view(material_id).value();
-                  mesh = new THREE.Mesh(geometry, material);
-                
-                  // and then finish creating like with other loaders 
-                    
-                  if (BODY_item.position) { 
-                    var position_mesh = item.get_mesh('position');
-                    _update_mesh_io({position: BODY_item.position}, position_mesh);
-                    delete (BODY_item.position);
-                  }
-                  if (BODY_item.scale) { 
-                    var scale_mesh = item.get_mesh('scale');
-                    _update_mesh_io({scale: BODY_item.scale}, scale_mesh);
-                    delete (BODY_item.scale);
-                  }
-                  if (BODY_item.rotation) { 
-                    var rotation_mesh = item.get_mesh('rotation');
-                    _update_mesh_io({rotation: BODY_item.rotation}, rotation_mesh);
-                    delete (BODY_item.rotation);
-                  }
-
-                  BODY_item.mesh = _update_mesh_io(BODY_item, mesh, true);
-                  BODY_item.mesh.name = 'the_mesh';
-                  
-                  
-                  if (loading_strategy != 'delay_placing' || item.auto_place_mesh()) {
-                    item.place_mesh(BODY_item.mesh);
-                  }
-                  try {
-                    console.log('loaded text geometry', BODY_item.id);
-                  } catch(e) {}
-                  
-                  finish_add(BODY_item.id);
-                  _update_materials(BODY_item.mesh);
-                  //end_callback();
-
-                });
-                result_ids.push(item_id.id);
-            
-                // out of forEach loop
-                return;
-              case 'torus': 
-                geometry = new THREE.TorusGeometry(shape_data.radius, shape_data.tube, shape_data.radialSegments, shape_data.tubularSegments, shape_data.arc);
-                break;
-              case 'torusknot': 
-                geometry = new THREE.TorusKnotGeometry(shape_data.radius, shape_data.tube, shape_data.radialSegments, shape_data.tubularSegments, shape_data.p, shape_data.q, shape_data.heightScale);
-                break;
-              case 'tube': 
-                geometry = new THREE.TubeGeometry(shape_data.path, shape_data.segments, shape_data.radius, shape_data.radiusSegments, shape_data.closed, shape_data.debug)
-                break;
-              case 'shape': 
-                geometry = new THREE.ShapeGeometry(shape_data.points);
-                break;
-              case 'extrude': 
-                geometry = new THREE.ExtrudeGeometry(shape_data.points, shape_data.extrude_settings);
-                break;
-              case 'grid': 
-                geometry = new THREE.GridHelper(shape_data.size, shape_data.step)
-                break;
-              default: 
-                geometry = new THREE.BoxGeometry(10,10,10);
-            }
-            if (geometry) {
-              if (BODY_item.geometry.shape == 'grid') {
-                // grid is not a geometry 
-                // ignore texture and material
-                if (Object.keys(BODY_item.texture).length) {
-                  console.info('grid projection does not support textures.');
-                }
-                if (BODY_item.material.grid_color) {
-                  var colors = this_awe.util.extend({
-                    grid_color: 0xCCCCCC,
-                    center_line_color: 0x666666
-                  }, BODY_item.material);
-                  geometry.setColors(colors.center_line_color, colors.grid_color);
-                }
-                mesh = geometry;
-              }
-              else {
-                var texture, material;
-                if (Object.keys(BODY_item.texture).length) {
-                  if (BODY_item.geometry.x) { // a cube
-                    BODY_item.texture.width = BODY_item.geometry.x; 
-                  }
-                  if (BODY_item.geometry.width) { // a plane
-                    BODY_item.texture.width = BODY_item.geometry.width; 
-                  }
-                  if (BODY_item.geometry.y) { // a cube
-                    BODY_item.texture.height = BODY_item.geometry.y; 
-                  }
-                  if (BODY_item.geometry.height) { // a plane
-                    BODY_item.texture.height = BODY_item.geometry.height; 
-                  }
-                    
-                  var capabilities = this_awe.util.get_capabilities('gum');
-                  if (BODY_item.texture.path == 'camerastream' && !capabilities.gum){
-                    
-                    delete(BODY_item.texture.path);
-                    BODY_item.texture.width = 800;
-                    BODY_item.texture.height = 600;
-                    BODY_item.texture.background_color = null;
-                    BODY_item.texture.label = 'camerastream texture is unsupported on this device';
-                    BODY_item.texture.font = '100px Arial';
-                  }
-                  // hidden projection textures start out as paused
-                  BODY_item.texture.paused = (BODY_item.visible != undefined ? !BODY_item.visible : false);
-                  BODY_item.texture.success_callback = function(){
-                    var event = new CustomEvent('texture_loaded', {detail: BODY_item.id});
-                    window.dispatchEvent(event);
-                  }
-                  var texture_id = this_awe.textures.add(BODY_item.texture);
-                  BODY_item.texture.id = texture_id.id;
-                  if (BODY_item.texture.color) {
-                    BODY_item.material.color = BODY_item.texture.color;
-                  }
-                  BODY_item.material.map = this_awe.textures.view(texture_id).value();
-                }
-/*
-                BODY_item.material.success_callback = function(){
-                  var event = new CustomEvent('material_loaded', {detail: BODY_item.id});
-                  window.dispatchEvent(event);
-                }
-*/
-                var material_id = this_awe.materials.add(BODY_item.material);
-                BODY_item.material.id = material_id.id;
-                var material = this_awe.materials.view(material_id).value();
-                mesh = new THREE.Mesh(geometry, material);
-              }
-            }
-          }
-          else if (BODY_item.geometry.path) {
-            var loader;
-            // get extension and detect file type
-            var file_extension = BODY_item.geometry.file_type ? BODY_item.geometry.file_type.toLowerCase() : (BODY_item.geometry.path.split('.').pop()).toLowerCase();
-            
-            var progress_callback = BODY_item.geometry.progress_callback && _type(BODY_item.geometry.progress_callback) == 'function' ? BODY_item.geometry.progress_callback : noop;
-            var start_callback = BODY_item.geometry.start_callback && _type(BODY_item.geometry.start_callback) == 'function' ? BODY_item.geometry.start_callback : noop;
-            var end_callback = BODY_item.geometry.end_callback && _type(BODY_item.geometry.end_callback) == 'function' ? BODY_item.geometry.end_callback : noop;
-            var error_callback = BODY_item.geometry.error_callback && _type(BODY_item.geometry.error_callback) == 'function' ? BODY_item.geometry.error_callback : noop;
-            
-
-            switch(file_extension) {
-              case 'obj':
-                if (BODY_item.material.path) {
-                  item = new awe_projection(BODY_item, self);
-                  item_id = self.constructor.prototype.add.call(self, item, HEAD); // super
-                  item.trigger_state(awe.OBJECT_STATES.DEFAULT);
-                  item.trigger_state(awe.OBJECT_STATES.LOADING);
-                  loader = new THREE.OBJMTLLoader(loading_manager);
-                  loader.load(BODY_item.geometry.path, BODY_item.material.path, function(mesh) {
-
-                    try {
-                      console.log('loaded mtl obj1', BODY_item.id, mesh.children[1].material.color);
-                    } catch(e) {}
-                                
-                    if (BODY_item.position) { 
-                      var position_mesh = item.get_mesh('position');
-                      _update_mesh_io({position: BODY_item.position}, position_mesh);
-                      delete (BODY_item.position);
-                    }
-                    if (BODY_item.scale) { 
-                      var scale_mesh = item.get_mesh('scale');
-                      _update_mesh_io({scale: BODY_item.scale}, scale_mesh);
-                      delete (BODY_item.scale);
-                    }
-                    if (BODY_item.rotation) { 
-                      var rotation_mesh = item.get_mesh('rotation');
-                      _update_mesh_io({rotation: BODY_item.rotation}, rotation_mesh);
-                      delete (BODY_item.rotation);
-                    }
-
-                    BODY_item.mesh = _update_mesh_io(BODY_item, mesh, true);
-                    item.place_mesh(BODY_item.mesh);
-                    
-                    try {
-                      console.log('loaded mtl obj2', BODY_item.id, mesh.children[1].material.color);
-                    } catch(e) {}
-                    
-                    finish_add(BODY_item.id);
-                    _update_materials(BODY_item.mesh);
-                    end_callback();
-                  }, progress_callback, error_callback);
-                }
-                else {
-                  loader = new THREE.OBJLoader(loading_manager);
-                  var texture;
-                  if (BODY_item.texture.path) {
-                    if (BODY_item.geometry.x) { // a cube
-                      BODY_item.texture.width = BODY_item.geometry.x; 
-                    }
-                    if (BODY_item.geometry.width) { // a plane
-                      BODY_item.texture.width = BODY_item.geometry.width; 
-                    }
-                    if (BODY_item.geometry.y) { // a cube
-                      BODY_item.texture.height = BODY_item.geometry.y; 
-                    }
-                    if (BODY_item.geometry.height) { // a plane
-                      BODY_item.texture.height = BODY_item.geometry.height; 
-                    }
-                      
-                    
-                    var capabilities = this_awe.util.get_capabilities('gum');
-                    if (BODY_item.texture.path == 'camerastream' && !capabilities.gum){
-                      delete(BODY_item.texture.path);
-                      BODY_item.texture.width = 800;
-                      BODY_item.texture.height = 600;
-                      BODY_item.texture.background_color = null;
-                      BODY_item.texture.label = 'camerastream texture is unsupported on this device';
-                      BODY_item.texture.font = '100px Arial';
-                    }
-                    // hidden textures start out as paused
-                    BODY_item.texture.paused = (BODY_item.visible != undefined ? BODY_item.visible : false);
-                    var texture_id = this_awe.textures.add(BODY_item.texture);
-                    BODY_item.texture.id = texture_id.id;
-                    texture = this_awe.textures.view(texture_id).value();
-                  }
-/*
-                  else {
-                    var texture_id = this_awe.textures.add();
-                    BODY_item.texture.id = texture_id.id;
-                    texture = this_awe.textures.view(texture_id);
-                  }
-*/
-                  item = new awe_projection(BODY_item, self);
-                  item_id = self.constructor.prototype.add.call(self, item, HEAD); // super
-                  item.trigger_state(awe.OBJECT_STATES.DEFAULT);
-                  item.trigger_state(awe.OBJECT_STATES.LOADING);
-                
-                  loader.load(BODY_item.geometry.path, function (mesh) {
-                    if (texture) {
-                      mesh.traverse(function (child) {
-                        if ( child instanceof THREE.Mesh ) {
-                          child.material.map = texture;
-                          child.material.needsUpdate = true;
-                        }
-                      });
-                    }
-                    BODY_item.mesh = _update_mesh_io(BODY_item, mesh, true);
-                    item.place_mesh(BODY_item.mesh);
-                    finish_add(BODY_item.id);
-                    end_callback();
-                    
-                  }, progress_callback, error_callback);
-                }
-                start_callback();
-                break;
-              case 'json':
-                // assimp json loader
-                item = new awe_projection(BODY_item, self);
-                item_id = self.constructor.prototype.add.call(self, item, HEAD); // super
-                item.trigger_state(awe.OBJECT_STATES.DEFAULT);
-                item.trigger_state(awe.OBJECT_STATES.LOADING);
-                
-                loader = new THREE.AssimpJSONLoader(loading_manager);
-  //              loader.options.convertUpAxis = true;
-                loader.load( BODY_item.geometry.path, function ( object ) {
-                  try {
-                    
-                  BODY_item.mesh = _update_mesh_io(BODY_item, object, true);
-                  item.place_mesh(BODY_item.mesh);
-                  finish_add(BODY_item.id);
-                  end_callback();
-                  
-                  }
-                  catch(e) { console.log(e); }
-                }, progress_callback, error_callback);
-                start_callback();
-                break;
-              case 'dae':
-                // collada loader
-                item = new awe_projection(BODY_item, self);
-                item_id = self.constructor.prototype.add.call(self, item, HEAD); // super
-                item.trigger_state(awe.OBJECT_STATES.DEFAULT);
-                item.trigger_state(awe.OBJECT_STATES.LOADING);
-                
-                loader = new THREE.ColladaLoader(loading_manager);
-                loader.options.convertUpAxis = true;
-                loader.load( BODY_item.geometry.path, function ( collada ) {
-                  dae = collada.scene;
-                  dae.traverse(function(child) {
-                    if ( child instanceof THREE.SkinnedMesh ) {
-                      var animation = new THREE.Animation( child, child.geometry.animation );
-                      // TODO - this will probably require setting scene_needs_update to work.
-                      animation.play();
-                    }
-                  });
-                  
-                  BODY_item.mesh = _update_mesh_io(BODY_item, dae, true);
-                  item.place_mesh(BODY_item.mesh);
-                  finish_add(BODY_item.id);
-                  end_callback();
-                }, progress_callback, error_callback);
-                start_callback();
-                break;
-              default:
-                console.warn('unknown file type', file_extension);
-                throw { code: 500, messgae: 'unknown file type: '+ file_extension};
-            }
-            
-            result_ids.push(item_id.id);
-        
-            // out of forEach loop
-            return;
-          }
-        }
-        else {
-          geometry = new THREE.BoxGeometry(10,10,10);
-          var material_id = this_awe.materials.add(BODY_item.material);
-          BODY_item.material.id = material_id.id;
-          
-          var material = this_awe.materials.view(material_id).value();
-          mesh = new THREE.Mesh(geometry, material);
-        }
-//        BODY_item.visible = parent.visible;
-        var mesh_data = awe.util.clone(BODY_item);
-        
-        var position, rotation, scale;
-        if (BODY_item.rotation) {
-          rotation = BODY_item.rotation;
-          delete (mesh_data.rotation);
-        }
-        if (BODY_item.position) {
-          position = BODY_item.position;
-          delete (mesh_data.position);
-        }
-        if (BODY_item.scale) {
-          scale = BODY_item.scale;
-          delete (mesh_data.scale);
-        }
-        
-        BODY_item.mesh = _update_mesh_io(mesh_data, mesh, true);
-        
-        item = new awe_projection(BODY_item, self);
-        
-        if (scale) {
-          _update_mesh_io({scale: scale}, item.get_mesh('scale'));
-        }
-        if (rotation) {
-          _update_mesh_io({rotation: rotation}, item.get_mesh('rotation'));
-        }
-        if (position) {
-          _update_mesh_io({position: position}, item.get_mesh('position'));
-        }
-        
-/*
-        // why was this here???
-        if (BODY_item.scale) {
-          for (var p in BODY_item.scale) {
-            if (BODY_item.scale.hasOwnProperty(p)) {
-              BODY_item.mesh.scale[p] = BODY_item.scale[p];
-            }
-          }
-        }
-*/
-        
-        
-        
-        item_id = self.constructor.prototype.add.call(self, item, HEAD); // super
-        
-        item.trigger_state(awe.OBJECT_STATES.DEFAULT);
-        item.trigger_state(awe.OBJECT_STATES.LOADING);
-        result_ids.push(item_id.id);
-        finish_add(BODY_item.id);
-      });
-      return { id: result_ids }; 
-    };
-    this_awe.constructor.prototype.projections.view = function(BODY, HEAD) {
-      if (!BODY) { BODY = {}; }
-      if (!HEAD) { HEAD = {}; }
-      return this.constructor.prototype.view.call(this, BODY, HEAD); // super
-    };
-    this_awe.constructor.prototype.projections.update = function(BODY, HEAD) {
-      if (!BODY) { BODY = {}; }
-      if (!HEAD) { HEAD = {}; }
-      if (!Array.isArray(BODY)) {
-        BODY = [BODY];
-      }
-      var return_result = {},
-        self = this;
-      
-      BODY.forEach(function(item){
-        if (item.data && item.where && item.where.id) {
-          var fields_updated = [],
-            rotation,
-            position,
-            scale,
-            texture;
-
-          if (item.data.position) {
-            fields_updated.push('position');
-            position = item.data.position;
-          }
-
-          if (item.data.scale) {
-            fields_updated.push('scale');
-            scale = item.data.scale;
-          }
-
-          if (item.data.rotation) {
-            fields_updated.push('rotation');
-            rotation = item.data.rotation;
-          }
-
-          if (item.data.texture) {
-            fields_updated.push('texture');
-            texture = item.data.texture;
-          }
-
-          if (fields_updated.length) {
-            HEAD.fields_updated = fields_updated;
-          }
-
-          if (!Array.isArray(item.where.id)) {
-            item.where.id = [item.where.id];
-          }
-
-          item.where.id.forEach(function(_id) {
-            try {
-              var projection = this_awe.projections.view(_id),  
-                data = projection.get_data();
-
-              if (!projection) {
-                //console.warn('no item to update');
-                return;
-              }
-
-              var position_mesh = projection.get_mesh('position'),
-                rotation_mesh = projection.get_mesh('rotation'),
-                scale_mesh = projection.get_mesh('scale'),
-                object_mesh = projection.get_mesh('object'),
-                texture_mesh = projection.get_three_mesh();
-
-            } catch(e) {
-              return console.warn(e);
-            };
-
-            if(item.data.animation && parseFloat(item.data.animation.duration) > 0) {
-              try {
-                _tween(_extend({
-                  object: projection,
-                  end_state: item.data
-                }, item.data.animation));
-              } catch(e) {
-                console.warn(e);
-              };
-            }
-            else {
-              try {
-                if (rotation) {
-                  _update_mesh_io({rotation: rotation}, rotation_mesh);
-                  delete (item.data.rotation);
-                }
-                if (position) {
-                  _update_mesh_io({position: position}, position_mesh);
-                  delete (item.data.position);
-                }
-                if (scale) {
-                  _update_mesh_io({scale: scale}, scale_mesh);
-                  delete (item.data.scale);
-                }
-
-                if (texture) {
-                  /* Can't do _update_mesh_io for texture since _update_mesh_io is being used when firstly adding projection */
-                  if (!texture_mesh) {
-                    throw 'Texture mesh is not available';
-                  }
-
-                  if (texture_mesh.geometry.x && texture_mesh.geometry.y) {
-                    /* A cube */
-                    texture.width = texture_mesh.geometry.x;
-                    texture.height = texture_mesh.geometry.y;
-                  }
-                  else if (texture_mesh.geometry.width && texture_mesh.geometry.height) {
-                    /* A plane */
-                    texture.width = texture_mesh.geometry.width;
-                    texture.height = texture_mesh.geometry.height;
-                  }
-
-                  var capabilities = this_awe.util.get_capabilities('gum');
-                  if (texture.path === 'camerastream' && !capabilities.gum) {
-                    delete texture.path;
-                    texture.width = 800;
-                    texture.height = 600;
-                    texture.background_color = null;
-                    texture.label = 'camerastream texture is unsupported on this device';
-                    texture.font = '100px Arial';
-                  }
-
-                  texture.paused = texture.hasOwnProperty('paused') ? !!(texture.paused) : true;
-                  var new_texture_id = this_awe.textures.add(texture);
-                  texture.id = new_texture_id.id;
-
-                  if (texture.color) {
-                    texture_mesh.material.color = texture.color;
-                  }
-
-                  if (texture_mesh.material && texture_mesh.material.map) {
-                    texture_mesh.material.map = this_awe.textures.view(new_texture_id).value();
-                    texture_mesh.material.needsUpdate = true;
-                  }
-
-                  /* Remove the old texture */
-                  if (data.texture && data.texture.id) {
-                    this_awe.textures.delete(data.texture.id);
-                  }
-
-                  /* Modify texture data */
-                  this_awe.util.extend(data.texture, texture);
-
-                  delete (item.data.texture);
-                }
-                
-                var mesh = _update_mesh_io(item.data, object_mesh);
-              } catch(e) {
-                console.warn(e);
-              }
-            }
-
-            var result = _clone(item);
-            result.mesh = mesh;
-            result.where.id = _id;
-            return_result[_id] = self.constructor.prototype.update.call(self, result, HEAD); // super
-          });
-        }
-      });
-      return return_result;
-    };
-    this_awe.constructor.prototype.projections.delete = function(BODY, HEAD) {
-      if (!BODY) { BODY = {}; }
-      if (!HEAD) { HEAD = {}; }
-      var projection;
-      if (typeof BODY == 'string' || typeof BODY == 'number') {
-        projection = this_awe.projections.view(BODY);
-        BODY = { id: BODY };
-      }
-      else if (BODY.id) {
-        projection = this_awe.projections.view(BODY.id);
-      }
-      
-      if (!projection) {
-        console.trace('cant delete',BODY);
-        return this.constructor.prototype.delete.call(this, BODY, HEAD); // super
-      }
-    
-      if (projection.material()) {
-        this_awe.materials.delete(projection.material().id)
-      }
-      if (projection.texture()) {
-        this_awe.textures.delete(projection.texture().id)
-      }
-      
-      if (projection.parent && typeof(projection.parent) == 'function')  {
-        try {
-          parent = projection.parent();
-          parent._remove_child(projection);
-          this_awe.scene_needs_rendering = 1;
-        }
-        catch(e) {}
-      }
-      else {
-        var mesh = projection.get_mesh();
-        if (mesh && mesh.parent) {
-          mesh.parent.remove(mesh);
-          this_awe.scene_needs_rendering = 1;
-        }
-        else {
-          console.log('no mesh to delete!', BODY, HEAD)
-        } 
-      }
-      
-      delete(_clickable_objects['projection-'+projection.id]);
-      
-      return this.constructor.prototype.delete.call(this, BODY, HEAD); // super
-    };
-
-    this_awe.constructor.prototype.textures = new awe_v8();
-    this_awe.constructor.prototype.textures._item_constructor = awe_texture;
-    this_awe.constructor.prototype.textures.add = function(BODY, HEAD) {
-      if (!BODY) { BODY = {}; }
-      if (!HEAD) { HEAD = {}; }
-      if (!Array.isArray(BODY)) {
-        BODY = [BODY];
-      }
-      var results = [],
-        self = this;
-
-      
-      BODY.forEach(function(BODY_item){
-        console.log('adding texture', BODY_item)
-        var id = "texture-"+random_id();
-        var success = BODY_item.success_callback ? BODY_item.success_callback : noop;
-        delete (BODY_item.success_callback);
-        if (BODY_item.path) {
-          var texture = new THREE.Texture();
-          texture.needsUpdate = true;
-          texture.minFilter = THREE.LinearFilter;
-          var paths = [];
-          var v = document.createElement('video');
-//           document.body.appendChild(v)
-          if (Array.isArray(BODY_item.path)) {
-            BODY_item.path.forEach(function(p){
-              var tmp_path = BODY_item.path[p];
-              var suffix = tmp_path.match(/\.(webm|mp4|ogg|ogv)/i);
-              if (suffix) {
-                if (suffix[1].toLowerCase() == "ogv") {
-                  suffix[1] = "ogg";
-                }
-                var can_play = v.canPlayType("video/"+suffix[1].toLowerCase());
-                if (can_play == "probably" || can_play == "maybe") {
-                  paths.push(BODY_item.path[p]);
-                }
-              }
-            });
-          } else if (BODY_item.path.match(/\.(webm|mp4|ogg|ogv)/i)) {
-            paths.push(BODY_item.path);
-          }
-          var capabilities = this_awe.util.get_capabilities('gum');
-          var settings = this_awe.util.get_settings('camerastream_poster|default_video_poster');
-          if (paths.length) {
-            
-  //          v.crossOrigin = BODY_item.cross_origin || "anonymous";
-//             v.src = path;
-            
-            paths.forEach(function(path){
-              var suffix = path.match(/\.(webm|mp4|ogg|ogv)/i);
-              var source = document.createElement('source');
-              source.setAttribute('src', path);
-              source.setAttribute('type', 'video/'+suffix[1].toLowerCase());
-              console.log(source, suffix[1]);
-              v.appendChild(source);
-            });
-            
-            var autoplay = true;
-            if (BODY_item.autoplay !== undefined) {
-              autoplay = BODY_item.autoplay;
-            }
-            else if (BODY_item.paused !== undefined) {
-              autoplay = !BODY_item.paused;
-            }
-            v.autoplay = autoplay;
-            v.load();
-            var c = document.createElement('canvas');
-            var cc = c.getContext('2d');
-            cc.fillStyle = "white";
-            cc.fillRect(0, 0, c.width, c.height);
-            
-            var poster;
-            if (BODY_item.poster) {
-              poster = BODY_item.poster;
-            }
-            else if(settings.default_video_poster) {
-              poster = settings.default_video_poster;
-            }
-            if (poster) {
-              var poster_img = new Image();
-              poster_img.onload = function(){
-                if (v.readyState == v.HAVE_NOTHING) {
-                  c.width = poster_img.width;
-                  c.height = poster_img.height;
-                  if (BODY_item.flip) {
-                    cc.translate(c.width, 0);
-                    cc.scale(-1, 1);
-                  }
-                  cc.drawImage(poster_img, 0, 0, c.width, c.height);
-                  if (BODY_item.flip) {
-                    // flip again - will get flipped once video loads metadata
-                    cc.translate(c.width, 0);
-                    cc.scale(-1, 1);
-                  }
-                  texture.needsUpdate = true;
-                }
-              };
-              poster_img.src = poster;
-              v.setAttribute('poster', poster);
-            }
-            var _resize = function(){
-              c.width = v.videoWidth || 320;
-              c.height = v.videoHeight || 240;
-              if (BODY_item.flip) {
-                cc.translate(v.videoWidth, 0);
-                cc.scale(-1, 1);
-              }
-            };
-            if (v.videoWidth && v.videoHeight) {
-              _resize();
-            }
-            else {
-              v.addEventListener('loadedmetadata', function (e) {
-                _resize();
-              }, false);
-            }
-            
-            var play = function(){
-              try {
-                inline_video_shim_toggle(v, true)
-
-                if (!inline_video_shim_required) {
-                  v.play();
-                }
-
-                if (!autoplay) {
-                  try {
-                    inline_video_shim_toggle(v, false);
-                    if (!inline_video_shim_required) {
-                      v.pause();
-                    }
-                    v.currentTime = 0;
-                  } catch(e) {}
-                }
-              } catch(e) { console.trace('play() error',e);}
-            }
-            window.addEventListener('touchstart', play, false);
-            
-            v.addEventListener('playing', function(){
-              if (!v.paused) {
-                window.removeEventListener('touchstart', play);
-              }
-            })
-            
-            play();
-            v.setAttribute('data-sourcetype', 'video')
-            v.setAttribute('data-textureid', id)
-            
-            if (BODY_item.loop !== undefined) {
-              v.loop = BODY_item.loop;
-            }
-            if (BODY_item.muted !== undefined) {
-              v.muted = BODY_item.muted;
-            }
-            
-            texture = new THREE.Texture(c);
-            texture.needsUpdate = true;
-            texture.minFilter = THREE.LinearFilter;
-            texture.video = v;
-            texture.cc = cc;
-          }
-          else if (BODY_item.path.match(/^camerastream$/i) && capabilities.gum) {
-            
-            var autoplay = true;
-            if (BODY_item.autoplay !== undefined) {
-              autoplay = BODY_item.autoplay;
-            }
-            if (BODY_item.paused !== undefined) {
-              autoplay = !BODY_item.paused;
-            }
-            v.autoplay = autoplay;
-            
-            var play = function(){
-              inline_video_shim_toggle(v, true);
-              if (!inline_video_shim_required) {
-                v.play();
-              }
-              if (!autoplay) {
-                try {
-                  inline_video_shim_toggle(v, false);
-                  if (!inline_video_shim_required) {
-                    v.pause();
-                  }
-                  v.currentTime = 0;
-                } catch(e) {}
-              }
-            }
-            v.go = function(){
-              
-              var vs = this_awe.video_stream();
-              window.removeEventListener('gum_ready', v.go, false);
-              window.addEventListener('touchstart', play, false);
-              v.addEventListener('playing', function(){
-                window.removeEventListener('touchstart', play);
-              })
-              
-              this_awe.util.connect_stream_to_src(vs.get_stream(), v, BODY_item.id);
-              v.load();
-              play();
-            }
-            
-            v.setAttribute('data-sourcetype', 'camerastream');
-            v.setAttribute('data-textureid', id)
-            
-            if (BODY_item.loop !== undefined) {
-              v.loop = BODY_item.loop;
-            }
-            if (BODY_item.muted !== undefined) {
-              v.muted = BODY_item.muted;
-            }
-            var width = v.videoWidth || 320;
-            var height = v.videoHeight || 240;
-            var c = document.createElement('canvas');
-            var cc = c.getContext('2d');
-            
-            c.width = width;
-            c.height = height;
-            
-            cc.fillStyle = "white";
-            cc.fillRect(0, 0, c.width, c.height);
-            
-            
-            var poster;
-            if (BODY_item.poster) {
-              poster = BODY_item.poster;
-            }
-            else if(settings.camerastream_poster) {
-              poster = settings.camerastream_poster;
-            }
-            if (poster) {
-              var poster_img = new Image();
-              poster_img.onload = function(){
-                if (v.readyState == v.HAVE_NOTHING) {
-                  c.width = poster_img.width;
-                  c.height = poster_img.height;
-                  if (BODY_item.flip) {
-                    cc.translate(c.width, 0);
-                    cc.scale(-1, 1);
-                  }
-                  cc.drawImage(poster_img, 0, 0, c.width, c.height);
-                  if (BODY_item.flip) {
-                    // flip again - will get flipped once video loads metadata
-                    cc.translate(c.width, 0);
-                    cc.scale(-1, 1);
-                  }
-                  texture.needsUpdate = true;
-                }
-              };
-              poster_img.src = poster;
-              v.setAttribute('poster', poster);
-            }
-            
-            var _resize = function(){
-              c.width = v.videoWidth || width;
-              c.height = v.videoHeight || height;
-              if (BODY_item.flip) {
-                cc.translate(v.videoWidth, 0);
-                cc.scale(-1, 1);
-              }
-            };
-            if (v.videoWidth && v.videoHeight) {
-              _resize();
-            }
-            else {
-              v.addEventListener('loadedmetadata', function (e) {
-                _resize();
-              }, false);
-            }
-            
-            cc.font = '20px sans-serif';
-            cc.textAlign = 'center';
-            cc.textBaseline = 'middle';
-            
-            cc.fillStyle = '#000000';
-            cc.fillText('LOADING TEXTURE', width/2, height/2, width);
-            
-            texture = new THREE.Texture(c);
-            texture.needsUpdate = true;
-            texture.minFilter = THREE.LinearFilter;
-            texture.video = v;
-            texture.cc = cc;
-            
-            if (!BODY_item.paused) {
-              if (!this_awe.video_stream()) {
-                this_awe.setup_stream();
-              }
-              var vs = this_awe.video_stream();
-              if (vs.is_stream_ready()) {
-                v.go();
-              }
-              else {
-                window.addEventListener('gum_ready', v.go, false);
-              }
-            }
-            else {
-              window.addEventListener('gum_ready', v.go, false);
-            }
-            
-          }
-          else if (BODY_item.path.match(/^stream$/i)) {
-            if (!BODY_item.source_element) {
-              throw { code: 500, message: 'texture.source_element required' };
-            }
-            var v = BODY_item.source_element;
-            var c = document.createElement('canvas');
-            var cc = c.getContext('2d');
-            cc.fillStyle = "white";
-            cc.fillRect(0, 0, c.width, c.height);
-            
-            var poster;
-            if (BODY_item.poster) {
-              poster = BODY_item.poster;
-            }
-            else if(settings.default_video_poster) {
-              poster = settings.default_video_poster;
-            }
-            if (poster) {
-              var poster_img = new Image();
-              poster_img.onload = function(){
-                if (v.readyState == v.HAVE_NOTHING) {
-                  c.width = poster_img.width;
-                  c.height = poster_img.height;
-                  if (BODY_item.flip) {
-                    cc.translate(c.width, 0);
-                    cc.scale(-1, 1);
-                  }
-                  cc.drawImage(poster_img, 0, 0, c.width, c.height);
-                  if (BODY_item.flip) {
-                    // flip again - will get flipped once video loads metadata
-                    cc.translate(c.width, 0);
-                    cc.scale(-1, 1);
-                  }
-                  texture.needsUpdate = true;
-                }
-              };
-              poster_img.src = poster;
-              v.setAttribute('poster', poster);
-            }
-            
-            var _resize = function(){
-              c.width = v.videoWidth || 320;
-              c.height = v.videoHeight || 240;
-              if (BODY_item.flip) {
-                cc.translate(v.videoWidth, 0);
-                cc.scale(-1, 1);
-              }
-            };
-            if (v.videoWidth && v.videoHeight) {
-              _resize();
-            }
-            else {
-              v.addEventListener('loadedmetadata', function (e) {
-                _resize();
-              }, false);
-            }
-            
-            var autoplay = true;
-            if (BODY_item.autoplay !== undefined) {
-              autoplay = BODY_item.autoplay;
-            }
-            if (BODY_item.paused !== undefined) {
-              autoplay = !BODY_item.paused;
-            }
-            v.autoplay = autoplay;
-            
-            var play = function(){
-              inline_video_shim_toggle(v, true);
-              if (!inline_video_shim_required) {
-                v.play();
-              }
-              if (!autoplay) {
-                try {
-                  inline_video_shim_toggle(v, false);
-                  if (!inline_video_shim_required) {
-                    v.pause();
-                  }
-                  v.currentTime = 0;
-                } catch(e) {}
-              }
-            }
-            window.addEventListener('touchstart', play, false);
-            v.addEventListener('playing', function(){
-              window.removeEventListener('touchstart', play);
-            });
-            play();
-            v.setAttribute('data-sourcetype', 'stream')
-            v.setAttribute('data-textureid', id)
-  
-            texture = new THREE.Texture(c);
-            texture.needsUpdate = true;
-            texture.minFilter = THREE.LinearFilter;
-            texture.video = v;
-            texture.cc = cc;
-          }
-          else {
-            texture = (new THREE.TextureLoader(loading_manager)).load(BODY_item.path, function(texture) {
-              texture.needsUpdate = true;
-              this_awe.scene_needs_rendering = 1;
-              try {
-                success();
-              }
-              catch(e){}
-            }, texture_loading_progress, texture_loading_error);
-            texture.needsUpdate = true;
-            texture.minFilter = THREE.LinearFilter;
-            if (BODY_item.wrap_s) {
-              // THREE.ClampToEdgeWrapping, where the edge is clamped to the outer edge texels. The other two choices are THREE.RepeatWrapping and THREE.MirroredRepeatWrapping.
-              texture.wrapS = BODY_item.wrap_s;
-            }
-            if (BODY_item.wrap_t) {
-              // THREE.ClampToEdgeWrapping, where the edge is clamped to the outer edge texels. The other two choices are THREE.RepeatWrapping and THREE.MirroredRepeatWrapping.
-              texture.wrapT = BODY_item.wrap_t;
-            }
-            if (BODY_item.repeat) {
-              texture.repeat.set(BODY_item.repeat.x || 1, BODY_item.repeat.y || 1)
-            }
-            if (BODY_item.flip) {
-              texture.wrapS = THREE.RepeatWrapping;
-              texture.repeat.x = -1;
-            }
-            
-          }
-          var item = new awe_texture({ id: id, texture: texture }, self);
-          results.push(item);
-        }
-        else if (BODY_item.label) {
-          // text on a canvas
-          var params = this_awe.util.extend({
-            width: 300,
-            height: 200,
-            
-            background_color: '#ffffff',
-            background_image: null,
-            text_style: 'fill', // fill / outline
-            text_color: '#000000',
-            text_align: 'center', // "left" || "right" || "center" || "start" || "end";
-            text_baseline: 'middle', //"top" || "hanging" || "middle" || "alphabetic" || "ideographic" || "bottom";
-            direction: 'inherit', // "ltr" || "rtl" || "inherit";
-            /*
-text_position_y: 0,
-            text_position_x: 0,
-*/
-            
-            line_width: 0,
-            line_cap: 'butt', // butt / round / square
-            line_join: 'round', // round / bevel / miter
-            miter_limit: 10,
-            line_dash: null,
-            line_dash_offset: 0,
-            
-            font: '20px sans-serif',
-            
-            shadow_offset_x: 0,
-            shadow_offset_y: 0,
-            shadow_blur: 0,
-            shadow_color: null,
-
-            max_width: undefined
-            
-          }, BODY_item);
-          // center label by default
-          if (params.text_position_x == undefined) {
-            params.text_position_x = params.width / 2;
-          }
-          if (params.text_position_y == undefined) {
-            params.text_position_y = params.height / 2;
-          }
-          
-          var c = document.createElement('canvas');
-          
-//           c.id = 'texture-canvas-'+id;
-//           document.body.appendChild(c);
-          
-          var cc = c.getContext('2d');
-          c.width = params.width;
-          c.height = params.height;
-          cc.fillStyle = "white";
-          cc.fillRect(0, 0, c.width, c.height);
-//           c.setAttribute('style','position: absolute;left: 0;top: 0;border: solid red 1px;z-index: 999'); // DEBUG
-
-          if (params.background_color) {
-            cc.fillStyle = params.background_color;
-            cc.fillRect(0,0,width,height);
-          }
-          /*
-if (params.background_image){
-            var img = new Image();
-            img.src = params.background_image;
-            img.onload = function(){
-              var ptrn = cc.createPattern(img,'repeat');
-              cc.fillStyle = ptrn;
-              cc.fillRect(0,0,width,height);
-              texture.needsUpdate = true;
-            };       
-          }
-          
-*/
-          if (parseInt(params.line_width) > 0) {
-            cc.strokeStyle = params.text_outline_color;
-            cc.lineWidth = params.line_width;
-          }
-          if (params.line_dash != null) {
-            cc.setLineDash(params.line_dash);
-            cc.lineDashOffset = params.line_dash_offset;
-          }
-          cc.lineCap = params.line_cap;
-          cc.lineJoin = params.line_join;
-          cc.miterLimit = params.miter_limit;
-          cc.font = params.font;
-          cc.textAlign = params.text_align;
-          cc.textBaseline = params.text_baseline;
-          cc.direction = params.direction;
-          
-          cc.fillStyle = params.text_color;
-          
-          if (params.text_style == 'fill'){
-            cc.fillText(params.label, params.text_position_x, params.text_position_y, params.max_width || params.width);
-          }
-          else {
-            cc.strokeText(params.label, params.text_position_x, params.text_position_y, params.max_width || params.width);
-          }
-          
-          var texture = new THREE.Texture(c);
-          texture.needsUpdate = true;
-          // 
-//          texture.cc = cc;
-          texture.minFilter = THREE.LinearFilter;
-          if (BODY_item.wrap_s) {
-            // THREE.ClampToEdgeWrapping, where the edge is clamped to the outer edge texels. The other two choices are THREE.RepeatWrapping and THREE.MirroredRepeatWrapping.
-            texture.wrapS = BODY_item.wrap_s;
-          }
-          if (BODY_item.wrap_t) {
-            // THREE.ClampToEdgeWrapping, where the edge is clamped to the outer edge texels. The other two choices are THREE.RepeatWrapping and THREE.MirroredRepeatWrapping.
-            texture.wrapT = BODY_item.wrap_t;
-          }
-          if (BODY_item.repeat) {
-            texture.repeat.set(BODY_item.repeat.x || 1, BODY_item.repeat.y || 1)
-          }
-          
-          texture.needsUpdate = true;
-          
-          var item = new awe_texture({ id: id, texture: texture }, self);
-          results.push(item);
-        }
-        else {
-          throw { code: 500, message: 'texture.path or texture.label required' };
-        }
-      });
-      
-      return this.constructor.prototype.add.call(this, results, HEAD); // super
-    } 
-    this_awe.constructor.prototype.textures.delete = function(BODY, HEAD) {
-      var texture;
-      if (typeof BODY == 'string' || typeof BODY == 'number') {
-        BODY = { id: BODY };
-      }
-      if (BODY.id) {
-        texture = this.constructor.prototype.view(BODY.id);
-      }
-      if (texture.is_video_texture()) {
-        window.removeEventListener('gum_ready', texture.texture.video.go, false);
-        texture.stop();
-        texture.texture.video.pause();
-        delete texture.texture.cc;
-        delete texture.texture.video;
-      }
-      delete texture;
-      return this.constructor.prototype.delete.call(this, BODY, HEAD); // super;
-    };
-
-    this_awe.constructor.prototype.materials = new awe_v8();
-    this_awe.constructor.prototype.materials._item_constructor = awe_material;
-    this_awe.constructor.prototype.materials.add = function(BODY, HEAD) {
-      if (!BODY) { BODY = {}; }
-      if (!HEAD) { HEAD = {}; }
-      if (!Array.isArray(BODY)) {
-        BODY = [BODY];
-      }
-      var results = [],
-        self = this;
-        
-      BODY.forEach(function(BODY_item){
-      
-        var id = BODY_item.id || "material-"+random_id();
-//         var success = BODY_item.success_callback || noop;
-        delete BODY_item.id;
-        var type = BODY_item.type || 'basic';
-        delete BODY_item.type;
-        if (!BODY_item.wireframe) {
-          BODY_item.wireframe = false;
-        }
-        if (!BODY_item.color) {
-          BODY_item.color = 0x404040;
-        }
-        var side = THREE.DoubleSide;
-        if (BODY_item.side) {
-          if (BODY_item.side == "front") {
-            side = THREE.FrontSide;
-          }
-          else if (BODY_item.side == "back") {
-            side = THREE.BackSide;
-          }
-          delete BODY_item.side;
-        }
-        if (!BODY_item.overdraw) {
-          BODY_item.overdraw = true;
-        }
-        var material;
-        
-        switch(type) {
-          case 'phong':
-            if (!BODY_item.shading) {
-              BODY_item.shading = THREE.SmoothShading;
-            }
-            material = new THREE.MeshPhongMaterial(BODY_item);
-            break;
-          case 'lambert':
-            material = new THREE.MeshLambertMaterial(BODY_item);
-            break;
-          case 'shader':
-            material = new THREE.ShaderMaterial(BODY_item);
-            break;
-          case 'sprite':
-            material = new THREE.SpriteMaterial(BODY_item);
-            break;
-          case 'sprite_canvas':
-            material = new THREE.SpriteCanvasMaterial(BODY_item);
-            break;
-          default: 
-            material = new THREE.MeshBasicMaterial(BODY_item);
-        }
-        material.side = side;
-        var item = new awe_material({ id: id, material: material }, self);
-//         success();
-        results.push(item);
-      })
-      return this.constructor.prototype.add.call(this, results, HEAD); // super
-    };
-
-    this_awe.constructor.prototype.sounds = new awe_v8();
-    this_awe.constructor.prototype.sounds._item_constructor = awe_sound;
-    this_awe.constructor.prototype.sounds.add = function(BODY, HEAD) {
-      var capabilities = this_awe.util.get_capabilities('audio');
-      if (capabilities.audio) {
-        if (!BODY) { BODY = {}; }
-        if (!HEAD) { HEAD = {}; }
-        var id = BODY.id || "sound-"+random_id();
-        delete BODY.id;
-        if (BODY.autoplay == undefined) {
-          BODY.autoplay = true;
-        }
-        _load_sound(BODY);
-        var item = new awe_sound(BODY, this);
-        return this.constructor.prototype.add.call(this, item, HEAD); // super
-      }
-    };
-          
-    this_awe.constructor.prototype.setup_scene = function(io) {
-      this.origin = { x: 0, y: 0, z: 0};
-      
-      io = _extend({
-        id: 'default'
-      }, io);
-      if (!this_awe.renderers.view('default')) {
-        this_awe.renderers.add({ id: 'default' });
-      }
-      this_awe.scenes.add({id: io.id, container_id: io.container_id });
-      this_awe.povs.add({id: io.id, scene_id: io.id});
-      var settings = this_awe.util.get_settings('start_video_stream|default_lights');
-      if (settings.start_video_stream) {
-        this_awe.setup_stream();
-      }
-      var lights = this_awe.lights.list();
-
-      if (!lights.length) {
-        if (settings.default_lights && Array.isArray(settings.default_lights)) { 
-          this_awe.lights.add(settings.default_lights);
-        }
-      }
-      frustum = new THREE.Frustum();
-      cameraViewProjectionMatrix = new THREE.Matrix4();
-
-      loading_manager = new THREE.LoadingManager();
-      loading_manager.onProgress = function ( item, loaded, total ) {
-        this_awe.scene_needs_rendering = 1;
-      }
-      
-      var renderer = this_awe.renderer();
-      var awe_canvas = renderer.get_canvas();
-      var aspect_ratio = awe_canvas.clientWidth / awe_canvas.clientHeight;
-      var pov = this_awe.pov();
-      
-      pov.set_aspect(aspect_ratio);
-      pov.update_projection_matrix();
-      
-      renderer.set_size(awe_canvas.clientWidth, awe_canvas.clientHeight, false);
-      this_awe.scene_needs_rendering = 1;
-      
-      this_awe.scene_ready = true;
-      var event = new CustomEvent('scene_ready');
-      window.dispatchEvent(event);
-      
-      console.log('scene_ready')
-      _tick();
-    };
-
-    this_awe.constructor.prototype.setup_stream = function(id) {
-      id = id ? id : 'default';
-      if (!this_awe.video_streams.view(id)) {
-        this_awe.video_streams.add({ id: id });
-      }
-    };
-
-    this_awe.constructor.prototype.resize_canvas = function(force) {
-      var renderer = this_awe.renderer(),
-        awe_canvas = renderer.get_canvas(),
-        pov = this_awe.pov(),
-        width = awe_canvas.clientWidth,
-        height = awe_canvas.clientHeight,
-        aspect = width / height;
-        
-      if (awe_canvas.width != width || awe_canvas.height != height || force) {
-        pov.set_aspect(aspect);
-        pov.update_projection_matrix();
-        renderer.set_size(width, height, false);
-        this_awe.scene_needs_rendering = 1;
-
-        var event = new CustomEvent('renderer_resized');
-        window.dispatchEvent(event);
-      }
-    };
-
-    this_awe.constructor.prototype.render = function() {
-      if (this_awe.scene_needs_rendering) {
-        // loop through all scenes
-        
-        var renderer = this_awe.renderer();
-        var scenes = this_awe.scenes.list();
-        var the_scene = this_awe.scene();
-        
-        if (scenes.length > 1) {
-          renderer.enableScissorTest( true );
-          scenes.forEach(function(item) {
-            var scene = item.value,
-              povs = awe.povs.list({exact: { scene_id: item.id }}),
-              pov;
-              
-            switch (povs.length) {
-              case 0:
-                // nothing to render
-                console.log('No pov in scene id '+item.id+' to render with');
-                return;
-              case 1:
-                pov = povs[0].value;
-                break;
-              default:
-                active_povs = awe.povs.list({exact: { scene_id: item.id, active: 1 }});
-                pov = active_povs.length ? active_povs[0].value : povs[0].value;
-            }
-            
-            // get the element that is a place holder for where we want to
-            // draw the scene
-            if (scene.element) {
-              var element = scene.element;
-    
-              // get its position relative to the page's viewport
-              var rect = element.getBoundingClientRect();
-    
-              // check if it's offscreen. If so skip it
-              if ( rect.bottom < 0 || rect.top  > renderer.domElement.clientHeight ||
-                rect.right  < 0 || rect.left > renderer.domElement.clientWidth ) {
-                return;  // it's off screen
-              }
-    
-              // set the viewport
-              var width  = rect.right - rect.left;
-              var height = rect.bottom - rect.top;
-              var left   = rect.left;
-              var bottom = renderer.domElement.clientHeight - rect.bottom;
-              
-              pov.aspect = width / height;
-              pov.updateProjectionMatrix();
-              
-              renderer.setViewport( left, bottom, width, height );
-              renderer.setScissor( left, bottom, width, height );
-            }
-            renderer.render( the_scene, pov );
-          });
-          renderer.enableScissorTest( false );
-        }
-        else {
-          renderer.render( the_scene, this_awe.pov() );
-        }
-        
-/*
-        for (var i=0,l=scenes.length, scene; i<l; i++) {
-          this_awe.renderer().render(scenes[i].value, this_awe.povs.view(scenes[i].id));
-        }
-*/
-        this_awe.scene_needs_rendering = 0;
-      }
-    };
-    var version = this_awe.version();
-    this_awe.constructor.prototype.version = function(){
-      return {
-        awe: version,
-        THREE: THREE.REVISION
-      }
-    }
-    
-    this_awe.constructor.prototype.animations = (function(){
-      return {
-        stop: function(objects){
-          var stop = function(mesh_id){
-            var mesh_tweens = tween_queue[mesh_id];
-            for (var property in mesh_tweens) {
-              if (mesh_tweens.hasOwnProperty(property)) {               
-                for (var i in mesh_tweens[property]) {
-                  if (mesh_tweens[property].hasOwnProperty(i)) {
-                    mesh_tweens[property][i].stop();
-                  }
-                } 
-              }
-            }
-            tween_queue[mesh_id] = {};
-          }
-          
-          if (!objects) {
-            for (var mesh_id in tween_queue) {
-              if (tween_queue.hasOwnProperty(mesh_id)) {
-                stop(mesh_id);
-              }
-            }
-            tween_queue = {};
-            return;
-          }
-          if (!Array.isArray(objects)) {
-            objects = [objects];
-          }
-          for (var i=0,l=objects.length; i<l; i++) {
-            try {
-              var object = this_awe[objects[i].object_type+'s'].view(objects[i].object_id);
-              if (object._tweens) {
-                Object.forEach(object._tweens, function(id, t){
-                  TWEEN.remove(t);
-                });
-              }
-              else {
-                var mesh = object.get_mesh();
-                if (mesh) {
-                  stop(mesh.id);
-                }
-              }
-            } catch(e) { console.log(e); }
-            
-          }
-        }
-      }
-    })();
-
-    function _get_mesh_state(mesh) {
-      try {
-        var accuracy = 7;
-        var state = {
-          material: {
-            opacity: mesh.material && mesh.material.transparent ? mesh.material.opacity: 1
-          },
-          rotation: {
-            x: parseFloat(THREE.Math.radToDeg(mesh.rotation.x).toFixed(accuracy)),
-            y: parseFloat(THREE.Math.radToDeg(mesh.rotation.y).toFixed(accuracy)),
-            z: parseFloat(THREE.Math.radToDeg(mesh.rotation.z).toFixed(accuracy))
-          },
-          scale: {
-            x: parseFloat(parseFloat(mesh.scale.x).toFixed(accuracy)),
-            y: parseFloat(parseFloat(mesh.scale.y).toFixed(accuracy)),
-            z: parseFloat(parseFloat(mesh.scale.z).toFixed(accuracy))
-          },
-          position: {
-            x: parseFloat(parseFloat(mesh.position.x).toFixed(accuracy)),
-            y: parseFloat(parseFloat(mesh.position.y).toFixed(accuracy)),
-            z: parseFloat(parseFloat(mesh.position.z).toFixed(accuracy))
-          }
-        };
-        if (mesh.target && mesh.target.position) {
-          state.target = {
-            x: parseFloat(parseFloat(mesh.target.position.x).toFixed(accuracy)),
-            y: parseFloat(parseFloat(mesh.target.position.y).toFixed(accuracy)),
-            z: parseFloat(parseFloat(mesh.target.position.z).toFixed(accuracy))
-          }
-        }
-        return state;
-      }
-      catch(e) {
-        console.error(e);
-      }
-    }
-    
-    function _transform(ob) {
-      ob = ob ? ob : {};
-      var def = {
-        rotation: {
-          x: 0,
-          y: 0,
-          z: 0
-        },
-        scale: {
-          x: 1,
-          y: 1,
-          z: 1
-        },
-        position: {
-          x: 0,
-          y: 0,
-          z: 0
-        }
-      };
-      this.rotation = _extend(def.rotation, ob.rotation);
-      this.scale = _extend(def.scale, ob.scale); 
-      this.position = _extend(def.position, ob.position);   
-      return this;
-    };
-
-    _transform.prototype.data = function(ob) {
-      return {
-        rotation: this.rotation,
-        scale: this.scale,
-        position: this.position
-      };
-    };
-
-    _transform.prototype.add = function(ob) {
-      if (ob.rotation) {
-        this.rotation.x += ob.rotation.x || 0;
-        this.rotation.y += ob.rotation.y || 0;
-        this.rotation.z += ob.rotation.z || 0;
-      }
-      if (ob.scale) {
-        this.scale.x *= ob.scale.x || 1;
-        this.scale.y *= ob.scale.y || 1;
-        this.scale.z *= ob.scale.z || 1;
-      }
-      if (ob.position) {
-        this.position.x += ob.position.x || 0;
-        this.position.y += ob.position.y || 0;
-        this.position.z += ob.position.z || 0;
-      }
-      return this;
-    };
-
-    function _validate_shape(geometry) {
-      var io = {};
-      if (!geometry.shape) {
-        return io;
-      }
-      switch(geometry.shape) {
-        case 'cube': 
-          io = {
-            x: 1,
-            y: 1,
-            z: 1
-          };
-          break;
-        case 'sphere': 
-          io = {
-            radius: 10
-          };
-          break;
-        case 'grid': 
-          io = {
-            size: 100,
-            step: 10
-          };
-          break;
-        case 'plane': 
-          io = {
-            width: 1,
-            height: 1,
-            widthSegments: 1,
-            heightSegments: 1
-          };
-        case 'text': 
-          io = {
-            text: 'theAWEsomeWEB',
-            font_url: '',
-            parameters: {}
-          };
-          break;
-      }
-      for (var i in geometry) {
-        if (geometry.hasOwnProperty(i)) {
-          io[i] = geometry[i];
-        }
-      }
-      return io;
-    }
-    
-    function _update_mesh_io(io, mesh, new_object) {
-      if (!io) {
-        io = {};
-      } else {
-        io = _clone(io);
-      }
-      
-      if (!io.geometry) {
-        io.geometry = {};
-      }
-      if (!io.material) {
-        io.material = {};
-      }
-      var render = false;
-      if (!mesh) {
-        var geometry = new THREE.BoxGeometry(io.geometry.x, io.geometry.y, io.geometry.z);
-        var material_id = this_awe.materials.add(io.material);
-        var material = this_awe.materials.view(material_id).value();
-        mesh = io.mesh || new THREE.Mesh(geometry, material);
-        render = true;
-      }
-      if (io.scale) {
-        if (io.scale.x !== undefined) { 
-          mesh.scale.x = io.scale.x; 
-        }
-        else if (new_object) { 
-          mesh.scale.x = 1; 
-        }
-        if (io.scale.y !== undefined) { 
-          mesh.scale.y = io.scale.y; 
-        }
-        else if (new_object) { 
-          mesh.scale.y = 1; 
-        }
-        if (io.scale.z !== undefined) { 
-          mesh.scale.z = io.scale.z; 
-        }
-        else if (new_object) { 
-          mesh.scale.z = 1; 
-        }
-        delete io.scale;
-        render = true;
-      }
-      if (io.rotation) {
-        if (io.rotation.x !== undefined) { 
-          mesh.rotation.x = THREE.Math.degToRad(io.rotation.x); 
-        }
-        else if (new_object) { 
-          mesh.rotation.x = 0; 
-        }
-        if (io.rotation.y !== undefined) { 
-          mesh.rotation.y = THREE.Math.degToRad(io.rotation.y); 
-        }
-        else if (new_object) { 
-          mesh.rotation.y = 0; 
-        }
-        if (io.rotation.z !== undefined) { 
-          mesh.rotation.z = THREE.Math.degToRad(io.rotation.z); 
-        }
-        else if (new_object) { 
-          mesh.rotation.z = 0; 
-        }
-        delete io.rotation;
-        render = true;
-      }
-      if (io.position) {
-        if (io.position.x !== undefined) { 
-          mesh.position.x = io.position.x; 
-        }
-        else if (new_object) { 
-          mesh.position.x = 0; 
-        }
-        if (io.position.y !== undefined) { 
-          mesh.position.y = io.position.y; 
-        }
-        else if (new_object) { 
-          mesh.position.y = 0; 
-        }
-        if (io.position.z !== undefined) { 
-          mesh.position.z = io.position.z; 
-        }
-        else if (new_object) { 
-          mesh.position.z = 0; 
-        }
-        delete io.position;
-        render = true;
-      }
-      if (io.target && mesh.target) {
-        
-        if (io.target.x !== undefined) { 
-          mesh.target.position.x = io.target.x; 
-        }
-        else if (new_object) { 
-          mesh.target.position.x = 0; 
-        }
-        if (io.target.y !== undefined) { 
-          mesh.target.position.y = io.target.y; 
-        }
-        else if (new_object) { 
-          mesh.target.position.y = 0; 
-        }
-        if (io.target.z !== undefined) { 
-          mesh.target.position.z = io.target.z; 
-        }
-        else if (new_object) { 
-          mesh.target.position.z = 0; 
-        }
-        delete io.target;
-        render = true;
-      }
-      if (!mesh.overdraw) {
-        try {
-          mesh.overdraw = true;
-          render = true;
-        }
-        catch(e) { /* TODO */ };
-      }
-      if (io.visible !== undefined) {
-        mesh.visible = !!io.visible;
-        mesh.traverse(function(child) {
-          if (!child._dont_traverse) {
-            child.visible = !!io.visible;
-          }
-        });
-        render = true;
-      }
-      if (io.cast_shadow !== undefined) {
-        mesh.castShadow = io.cast_shadow;
-        mesh.traverse(function(child) {
-          if (!child._dont_traverse) {
-            child.castShadow = io.cast_shadow;
-          }
-        });
-        render = true;
-      }
-      if (io.receive_shadow !== undefined) {
-        mesh.receiveShadow = io.receive_shadow;
-        mesh.traverse(function(child) {
-          if (!child._dont_traverse) {
-            child.receiveShadow = io.receive_shadow;
-          }
-        });
-        render = true;
-      }
-      if (io.matrix_auto_update !== undefined) {
-        mesh.matrixAutoUpdate = io.matrix_auto_update;
-        render = true;
-      }
-      if (io.custom_matrix !== undefined) {
-        mesh.customMatrix = io.custom_matrix;
-        render = true;
-      }
-      if (io.euler_order !== undefined) {
-        mesh.rotation.order = io.euler_order;
-        render = true;
-      }
-      if (io.material.color !== undefined) {
-        var c = _parse_color(io.material.color);
-        try {
-          // THREE.Group / THREE.Object3D does not have a material applied directly
-          if (mesh.material) {
-            mesh.material.color.setHex(c);
-          }
-          mesh.traverse(function(child) {
-            if (child.material && !child._dont_traverse) {
-              child.material.color.setHex(c);
-            }
-          });
-          render = true;
-        }
-        catch(e) { /* TODO */ };
-      }
-      if (io.material.opacity !== undefined) {
-        try {
-          // THREE.Group / THREE.Object3D does not have a material applied directly
-          if (mesh.material) {
-            mesh.material.opacity = io.material.opacity;
-          }
-          mesh.traverse(function(child) {
-            if (child.material && !child._dont_traverse) {
-              child.material.opacity = io.material.opacity;
-            }
-          });
-          render = true;
-        }
-        catch(e) { console.log('opacity error', e) /* TODO */ };
-      }
-      if (io.material.transparent !== undefined) {
-        try {
-          // THREE.Group / THREE.Object3D does not have a material applied directly
-          if (mesh.material) {
-            mesh.material.transparent = !!io.material.transparent;
-          }
-          mesh.traverse(function(child) {
-            if (child.material && !child._dont_traverse) {
-              child.material.transparent = !!io.material.transparent;
-            }
-          });
-          render = true;
-        }
-        catch(e) { /* TODO */ };
-      }
-      if (io.material.wireframe !== undefined) {
-        try {
-          // THREE.Group / THREE.Object3D does not have a material applied directly
-          if (mesh.material) {
-            mesh.material.wireframe = io.material.wireframe;
-          }
-          mesh.traverse(function(child) {
-            if (child.material && !child._dont_traverse) {
-              child.material.wireframe = io.material.wireframe;
-            }
-          });
-          render = true;
-        }
-        catch(e) { /* TODO */ };
-      }
-      if (io.material.fog !== undefined) {
-        try {
-          // THREE.Group / THREE.Object3D does not have a material applied directly
-          if (mesh.material) {
-            mesh.material.fog = io.material.fog;
-          }
-          mesh.traverse(function(child) {
-            if (child.material && !child._dont_traverse) {
-              child.material.fog = io.material.fog;
-            }
-          });
-          render = true;
-        }
-        catch(e) { /* TODO */ };
-      }
-      if (render) {
-        this_awe.scene_needs_rendering = 1;
-      }
-      delete io.geometry;
-      return mesh;
-    }
-    
-    var tween_queue = {};
-    
-    function _tween(io) {
-      try {
-        if (!io.mesh && !io.object) { 
-          throw  { code: 500, message: '_tween(): mesh/object not defined' };
-        }
-        if (!io.end_state) { 
-          throw  { code: 500, message: '_tween(): end_state not defined' };
-        }
-        var tween_id = io.mesh ? io.mesh.id : io.object.id;
-        var previous_tween;
-        if (tween_queue[tween_id] && Object.keys(tween_queue[tween_id]).length && (io.run_immediately != undefined && !io.run_immediately)) {
-//           previous_tween = // TBD...
-          console.warn('already animating this mesh ('+tween_id+')', tween_queue[tween_id], io.object._tweens);
-          return [];
-        }
-      }
-      catch(e) {
-        console.log(e);
-        this_awe.error_handler(e);
-        return [];
-      }
-      io = _extend({
-        duration: 1, // seconds
-        delay: 0, // seconds
-        persist: 1,
-        repeat: 0,
-        easing: 'LinearNone',
-        run_immediately: 1 // allow creating tweens to be run later
-      }, io);
-      var easing_function,
-        easing = io.easing.replace(/([A-Z])/g, ' $1').split(' ');
-        
-      easing.shift();
-      var _1 = easing.shift(), 
-        _2 = easing.join('');
-      try {
-        if (!TWEEN.Easing[_1] || !TWEEN.Easing[_1][_2]) {
-          throw {code: 500, message: 'Unsupported easing functions. See TWEEN.Easing for available easing functions.'};
-        }
-        easing_function = TWEEN.Easing[_1][_2]
-      }
-      catch(e) {
-        console.log(e);
-        this_awe.error_handler(e);
-      }
-      if (io.mesh) {
-        var start_state = _get_mesh_state(io.mesh);  
-      }
-      else {
-        var accuracy = 7;
-        var start_state = {
-          material: {
-            opacity: io.object.opacity || 1
-          },
-          rotation: {
-            x: parseFloat(io.object.rotation.x.toFixed(accuracy)),
-            y: parseFloat(io.object.rotation.y.toFixed(accuracy)),
-            z: parseFloat(io.object.rotation.z.toFixed(accuracy))
-          },
-          scale: {
-            x: parseFloat(io.object.scale.x.toFixed(accuracy)),
-            y: parseFloat(io.object.scale.y.toFixed(accuracy)),
-            z: parseFloat(io.object.scale.z.toFixed(accuracy))
-          },
-          position: {
-            x: parseFloat(io.object.position.x.toFixed(accuracy)),
-            y: parseFloat(io.object.position.y.toFixed(accuracy)),
-            z: parseFloat(io.object.position.z.toFixed(accuracy))
-          }
-        };
-/* // TODO
-        if (mesh.target && mesh.target.position) {
-          state.target = {
-            x: parseFloat(parseFloat(mesh.target.position.x).toFixed(accuracy)),
-            y: parseFloat(parseFloat(mesh.target.position.y).toFixed(accuracy)),
-            z: parseFloat(parseFloat(mesh.target.position.z).toFixed(accuracy))
-          }
-        }     
-*/
-      }
-
-      var initial_state = _clone_deep(start_state);
-      
-      
-      if (!tween_queue[tween_id]) {
-        tween_queue[tween_id] = {};
-      }
-      
-      var index = 'tween-'+random_id();
-      var tweens = [];
-
-      ['rotation', 'position', 'scale', 'material', 'target'].forEach(function(param, i){
-        
-        var mesh;
-        if (io.mesh) {
-          mesh = io.mesh;
-        }
-        else if (io.object && io.object.get_mesh) {
-          // get the correct mesh
-          mesh = io.object.get_mesh(param);
-        }
-        if (!mesh) {
-          console.trace('no mesh to animate');
-          return;
-        }
-        
-        if (io.end_state[param] != undefined) {
-          // compare start and end state and run only if different
-          var run = false;
-          for (var j in io.end_state[param]) {
-            if (io.end_state[param].hasOwnProperty(j) && io.end_state[param][j] != start_state[param][j]) {
-              run = true;
-              break;
-            }
-          }
-          if (!run) {
-            return;
-          }
-          var d = {};
-          d[param] = {};
-          var tween = new TWEEN.Tween( start_state[param] );
-          
-          var last_progress = 0, loop = 0;
-          if (!io.object._tweens) {
-            io.object._tweens = {};
-          }
-          if (io.object._tweens[param]) {
-            // stop the tween!
-            TWEEN.remove(io.object._tweens[param]);
-          }
-          io.object._tweens[param] = tween;
-          
-          tweens.push(tween);
-          tween.to( io.end_state[param], io.duration * 1000 )
-          .repeat( io.repeat )
-          .delay( io.delay * 1000)
-  //        .yoyo( true )
-          .easing( easing_function )
-          .onUpdate( function(progress) {
-            d[param] = this;
-            _update_mesh_io(d, mesh);
-            if (io.object && io.object._values_updated) {
-//               io.object._values_updated(); // removed to optimise
-            }
-            if (io.step_callback) {
-              io.step_callback(io);
-            }
-            if (io.loop_callback) { // track loops only if loop_callback is set
-              if (progress < last_progress) { // repeating progress
-                loop++;
-                io.loop_callback(io, loop);
-              }
-              last_progress = progress
-            }
-          })
-          .onStop(function(){
-            console.log('stop tween', io.end_state[param])
-            if (!io.persist) {
-              _update_mesh_io(initial_state, mesh);
-              if (io.object && io.object._values_updated) {
-                io.object._values_updated();
-              }
-            }
-            // clear queue? or is this just a "pause animation" thing?
-          })
-          .onComplete(function(){
-            console.log('complete',io.persist);
-            delete(tween_queue[tween_id][index][param]);
-            if (!Object.keys(tween_queue[tween_id][index]).length) {
-              delete(tween_queue[tween_id][index])
-            }
-            
-            delete(io.object._tweens[param]);
-            
-            if (!io.persist) {
-              _update_mesh_io(initial_state, mesh);
-              
-//               console.log('updated to initial state', initial_state);
-              if (io.object && io.object._values_updated) {
-                io.object._values_updated();
-              }
-            }
-            if (io.end_callback) {
-//             console.log('end callback called');
-              io.end_callback(io);
-            }
-          })
-          .onStart(function(){
-//             console.log('start tween', io.end_state[param], initial_state.scale)
-            if (!tween_queue[tween_id][index]) {
-              tween_queue[tween_id][index] = {};
-            }
-            tween_queue[tween_id][index][param] = tween;
-            
-            if (io.start_callback) {
-              io.start_callback(io);
-            }              
-          });
-          if (io.run_immediately) {
-            tween.start();
-          }
-        }
-        else {
-          delete (initial_state[param]);
-        }
-      });
-      return tweens;
-    }
-    
-    function _load_sound(io) {
-      if (io.path == undefined) {
-        throw 'url required';
-      }
-      var request = new XMLHttpRequest();
-      request.open('GET', io.path, true);
-      request.responseType = 'arraybuffer';
-      request.onload = function() {
-        this_awe.util.audio_context.decodeAudioData(request.response, function(new_buffer) {
-          io.buffer = new_buffer;
-          if (io.autoplay) {
-            _play_sound(io);
-          }
-          if (io.callback) {
-            try {
-              io.callback(io);
-            }
-            catch(e) {  };
-          }
-        }, function(e) { console.log(e); });
-      }
-      request.send();
-    }
-
-    function _play_sound(io) {
-      if (io.source == undefined) {
-        throw 'source required'; 
-      }
-      if (io.buffer == undefined) {
-        throw 'buffer required'; 
-      }
-      try {
-        io.source.buffer = io.buffer;
-        if (io.loop == undefined) {
-          io.source.loop = true;
-        }
-        else {
-          io.source.loop = io.loop;
-        }
-        io.source.start(io.start || 0.0);
-      }
-      catch(e) { };
-    }
-
-    function _map_audio_listener_to_pov() {
-      var capabilities = this_awe.util.get_capabilities('audio');
-      if (capabilities.audio) {
-        var m = this_awe.pov().get_mesh().matrix;
-        var mx = m.n14, my = m.n24, mz = m.n34;
-        m.n14 = m.n24 = m.n34 = 0;
-        var vec = new THREE.Vector3(0,0,1);
-        vec.applyMatrix4(m);
-        vec.normalize();
-        
-        var up = new THREE.Vector3(0,1,0);
-        up.applyMatrix4(m);
-        up.normalize();
-        
-        this_awe.util.audio_context.listener.setOrientation(vec.x, vec.y, vec.z, up.x, up.y, up.z);
-        m.n14 = mx;
-        m.n24 = my; 
-        m.n34 = mz;
-      }
-    }
-    
-    function _update_materials(mesh){
-      // after lighting change all visible objects need to have their material.needsUpdate flags set to true and re-rendered
-      // awe.materials() does not hold materials that got loaded via loaders, 
-      // so we will traverse the three scene children to make sure we reach all materials
-      var count = 0;
-      this_awe.scene().get_three_scene().traverse( function ( node ) {
-        if (node.material && !node._dont_traverse) {
-          node.material.needsUpdate = true;
-          count++;
-          if ( node.material instanceof THREE.MeshFaceMaterial ) {
-            for ( var i = 0; i < node.material.materials.length; i ++ ) {
-              node.material.materials[ i ].needsUpdate = true;
-              count++;
-            }
-          }
-        }
-      });
-    }
-
-    function _valid_coordinates(io) {
-      // extract just the x y and z and make sure they are numeric values
-      try {
-        if (!isNaN(parseFloat(io.x) + parseFloat(io.y) + parseFloat(io.z))) {
-          return {
-            x: io.x,
-            y: io.y,
-            z: io.z
-          };
-        }
-      }
-      catch (e) {}
-      return null;
-    }
-    
-    function _to_scene_coordinates(screen_coordinates, z) {
-      var projector = new THREE.Projector();
-      var ray = new THREE.Ray();
-      var camera = awe.pov().get_mesh();
-      var canvas = awe.renderer().get_canvas();
-            
-      var x = (screen_coordinates.x/canvas.clientWidth) * 2 - 1;
-      var y = -(screen_coordinates.y/canvas.clientHeight) * 2 + 1;
-      var mouse_vector = new THREE.Vector3(x, y, 1);
-      mouse_vector.unproject(camera); 
-      var direction = mouse_vector.sub(camera.position).normalize();
-      ray.set(camera.position, direction);
-      
-      var plane = new THREE.Plane(new THREE.Vector3(0,0,1), -z);
-      var point = ray.intersectPlane(plane);
-
-      return {
-        x: point.x,
-        y: point.y,
-        z: point.z
-      };
-      
-    }
-    function _to_screen_coordinates(scene_coordinates) {
-  
-      var camera = awe.pov().get_mesh();
-      var frustum = new THREE.Frustum();
-      var cameraViewProjectionMatrix = new THREE.Matrix4();
-      var canvas = awe.renderer().get_canvas();
-
-      camera.updateMatrixWorld(); // make sure the camera matrix is updated
-      camera.matrixWorldInverse.getInverse( camera.matrixWorld );
-      cameraViewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
-      frustum.setFromMatrix( cameraViewProjectionMatrix );
-      
-      // frustum is now ready to check all the objects you need
-      var vector = new THREE.Vector3(scene_coordinates.x, scene_coordinates.y, scene_coordinates.z);
-      if (frustum.containsPoint(vector)) {
-        var width = canvas.clientWidth, height = canvas.clientHeight;
-        var widthHalf = width / 2, heightHalf = height / 2;
-        
-        var projector = new THREE.Projector();
-        vector.project( camera );
-        
-        vector.x = ( vector.x * widthHalf ) + widthHalf;
-        vector.y = - ( vector.y * heightHalf ) + heightHalf;
-        return { x: vector.x, y: vector.y};
-      
-      }
-
-    }
-    function _color_hex_string(hex){
-      var c = new THREE.Color(hex);
-      return c.getHexString();
-    }
-    
-    function _parse_color(color){
-      var hex;
-      if (color.charAt && color.charAt(0) == '#') {
-        hex = color.substring(1);
-      }
-      else if (color.substring && color.substring(0,2) == '0x') {
-        hex = parseInt(color,16);
-      }
-      else if (typeof color == 'number') {
-        hex = color.toString(16);
-      }
-      else {
-        
-        console.warn('invalid material color, defaulting to #ffffff', color);
-        hex = 'ffffff';
-      }
-      return parseInt(hex,16);
-    }
-    
-    
-    function _make_three_vector(xyz){
-      if (!isNaN(xyz.x) && !isNaN(xyz.y) && !isNaN(xyz.z)) {
-        return new THREE.Vector3(xyz.x, xyz.y, xyz.z);
-      }
-      console.warn('util.make_three_vector(): not a valid 3d point',xyz);
-      return null;
-    }
-    
-    function _tick() {
-      try {
-        var textures = this_awe.textures.list(),
-          textures_updated = false;
-        textures.forEach(function(awe_texture){
-          if (awe_texture.is_video_texture()) {
-            textures_updated = awe_texture.update_video_texture() || textures_updated;
-          }
-        });
-        if (textures_updated) {
-          this_awe.scene_needs_rendering = 1;
-        }
-
-        // add throttle here if required
-        TWEEN.update();
-        this_awe.resize_canvas();
-        this_awe.render();
-        
-        requestAnimationFrame(function() {
-          var event = new CustomEvent('pretick');
-          window.dispatchEvent(event);
-          _tick();
-          var event = new CustomEvent('tick');
-          window.dispatchEvent(event);
-        });
-      } 
-      catch(e) {
-        this_awe.error_handler(e);
-      }
-    }
-    function _add_clickable_object(id, mesh){
-      if (!_clickable_objects[id]) {
-        _clickable_objects[id] = mesh;
-      }
-    }
-    function _delete_clickable_object(id){
-      delete(_clickable_objects[id]);
-    }
-    function _check_parent(object_data){
-      if (object_data.parent) {
-        return !!(this_awe[object_data.parent.object_type+'s'] && this_awe[object_data.parent.object_type+'s'].view(object_data.parent.object_id));
-      }
-      return true;
-    }
-    function random_id() {
-      return Date.now()+'-'+Math.round(Math.random()*1000);
-    }
-    
-    
-    var _look_at = function() {
-    	return function ( vector ) {
-      	var m1 = new THREE.Matrix4();
-    		m1.lookAt( this.getWorldPosition(), vector, this.up );
-    		this.quaternion.setFromRotationMatrix( m1 );
-    	};
-    }();
-
-    var _create_pov_quaternion = function (alpha, beta, gamma, screen_orientation) {
-      var init = false;
-      if (this_awe.pov_quaternion == undefined) {
-        init = true;
-        this_awe.pov_quaternion = {
-          screen_orientation:screen_orientation,
-          alpha:alpha,
-          beta:beta,
-          gamma:gamma,
-        };
-      }
-      var pq = this_awe.pov_quaternion;
-      if (init || pq.screen_orientation !== screen_orientation || pq.alpha !== alpha || pq.beta !== beta || pq.gamma !== gamma) {
-        var final_quaternion = new THREE.Quaternion();
-        var device_euler = new THREE.Euler();
-        var screen_transform = new THREE.Quaternion();
-        var world_transform = new THREE.Quaternion( - Math.sqrt(0.5), 0, 0, Math.sqrt(0.5) ); // - PI/2 around the x-axis
-        var adjustment_transform = new THREE.Quaternion();
-        adjustment_transform.setFromAxisAngle( new THREE.Vector3( 1, 0, 0 ), 90 * Math.PI / 180 ); // rotate the world by 90degrees
-        var minus_half_angle = 0;
-
-        device_euler.set( beta, alpha, - gamma, 'YXZ' );
-        final_quaternion.setFromEuler( device_euler );
-        minus_half_angle = - screen_orientation / 2;
-        screen_transform.set( 0, 0, Math.sin( minus_half_angle ), Math.cos( minus_half_angle ) );
-        if ( alpha !== 0 ) {
-          final_quaternion.multiply( world_transform );
-        }
-        final_quaternion.multiply( screen_transform );
-        pq.quaternion = final_quaternion;
-      }
-      return pq.quaternion;
-    };
-
-    var _update_pov_quaternion = function(orientation_data, screen_orientation, zoom, zoom_delta, last_update, mode) {
-      var alpha, beta, gamma, orient;
-      var obj_quat;
-      var now = performance.now();
-      var delta = now-last_update;
-      last_update = now;
-      orient = THREE.Math.degToRad( screen_orientation || 0 ); // O
-      if (mode == 'point') {
-        alpha  = THREE.Math.degToRad( orientation_data.alpha || 0 ); // Z
-        beta   = THREE.Math.degToRad( orientation_data.beta  || 0 ); // X'
-        gamma  = THREE.Math.degToRad( orientation_data.gamma || 0 ); // Y''
-
-        // only process non-zero 3-axis data
-        if ( alpha !== 0 && beta !== 0 && gamma !== 0) {
-          obj_quat = this_awe.util.create_pov_quaternion( alpha, beta, gamma, orient );
-          awe.pov().get_mesh().quaternion.copy( obj_quat );
-          awe.scene_needs_rendering = 1;
-        }
-      }
-      else if (mode == 'sphere') {
-        if (orient == 0) {  // portrait
-          alpha  = THREE.Math.degToRad( orientation_data.alpha+90 || 0 ); // Z
-          beta   = THREE.Math.degToRad( orientation_data.beta || 0 ); // X'
-          gamma  = THREE.Math.degToRad( orientation_data.gamma || 0 ); // Y''
-        } else if (orient > 0) { // right landscape
-          alpha  = THREE.Math.degToRad( orientation_data.alpha+180 || 0 ); // Z
-          beta   = THREE.Math.degToRad( orientation_data.beta || 0 ); // X'
-          gamma  = THREE.Math.degToRad( orientation_data.gamma || 0 ); // Y''
-        } else { // left landscape
-          alpha  = THREE.Math.degToRad( orientation_data.alpha || 0 ); // Z
-          beta   = THREE.Math.degToRad( orientation_data.beta || 0 ); // X'
-          gamma  = THREE.Math.degToRad( orientation_data.gamma || 0 ); // Y''
-        }
-
-        var new_alpha = -orientation_data.alpha;
-        var x = Math.cos(THREE.Math.degToRad(new_alpha));
-        var z = Math.sin(THREE.Math.degToRad(new_alpha));
-
-        var new_zoom = zoom+zoom_delta;
-
-        awe.pov().update({
-          position: {
-            x: new_zoom*x,
-            y: new_zoom,
-            z: (0.77*new_zoom)*z
-          }
-        });
-
-        awe.pov().look_at(awe.origin);
-
-        var new_quat = this_awe.util.create_pov_quaternion( alpha, beta, gamma, orient );
-        awe.pov().get_mesh().quaternion.copy( new_quat ); // no smoothing
-
-        awe.scene_needs_rendering = 1;
-      }
-    };
-    
-    this_awe.util.to_scene_coordinates = _to_scene_coordinates;
-    this_awe.util.to_screen_coordinates = _to_screen_coordinates;
-    this_awe.util.make_three_vector = _make_three_vector;
-    this_awe.util.create_pov_quaternion = _create_pov_quaternion;
-    this_awe.util.update_pov_quaternion = _update_pov_quaternion;
-    this_awe.util._update_mesh_io = _update_mesh_io;
-    this_awe.util.parse_color = _parse_color;
-    this_awe.util.color_hex_string = _color_hex_string;
-    this_awe.util.tween = _tween;
-    this_awe.util.add_clickable_object = _add_clickable_object;
-    this_awe.util.delete_clickable_object = _delete_clickable_object;
-    this_awe.util.inline_video_shim_toggle = inline_video_shim_toggle;
-    var _extend = this_awe.util.extend;
-    var _clone = this_awe.util.clone;
-    var _clone_deep = this_awe.util.clone_deep;
-    var _type = this_awe.util.type;
-    
-  } else {
-    throw "awe does not exist";
-  }
-})(window);
diff --git a/js/awe-v8.js b/js/awe-v8.js
deleted file mode 100755
index 1cdc632..0000000
--- a/js/awe-v8.js
+++ /dev/null
@@ -1,769 +0,0 @@
-// BEGIN FILE:  awe_v8.js
-// See: https://github.com/buildar/awe.js/blob/master/awe_v8.js
-/*
-
-  The MIT License
-
-  Copyright (c) 2013 Rob Manson, http://buildAR.com. All rights reserved.
-
-  Permission is hereby granted, free of charge, to any person obtaining a copy
-  of this software and associated documentation files (the "Software"), to deal
-  in the Software without restriction, including without limitation the rights
-  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-  copies of the Software, and to permit persons to whom the Software is
-  furnished to do so, subject to the following conditions:
-
-  The above copyright notice and this permission notice shall be included in
-  all copies or substantial portions of the Software.
-
-  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-  THE SOFTWARE.
-
-
-  What is awe_v8.js?
-  ------------------
-
-    It's a simple datastore template that makes it easy to store, manage and
-    extend collections of javascript object in a consistent way. 
-
-    Trust me, it's funkier than that sounds! 8)
-
-
-  Why is it called awe_v8?
-  ------------------------
-
-    Each datastore by default is designed to support a standard set of "8 verbs".
-
-    - search
-    - list
-    - add
-    - view
-    - edit
-    - update
-    - delete
-    - report
-
-    Through the magical process of simplification this translates in a subset of
-    "6 implemented methods".
-
-    - list
-    - add
-    - view
-    - update
-    - delete
-    - report
-
-    search and edit are simply UIs that drive one of these 6 methods.
-
-      e.g. edit -> update or search -> list
-
-
-  How are errors handled?
-  -----------------------
-
-    In simple js mode a method call either returns undefined for an error or
-    either an object or an array of 0 or more objects.
-
-
-  How do you use awe_v8? 
-  ----------------------
-
-  // create a awe_v8 datastore
-  var my_datastore = new awe_v8();
-
-  // add one object to your datastore
-  console.log("add an object (return new id)");
-  my_datastore.add({
-    id: "test",
-    some_data: "blah"
-  });
-
-  // add multiple objects to your datastore in one go
-  console.log("add several objects (return new ids)");
-  my_datastore.add([
-    {
-      id: "test2",
-      some_data: "blahdeblah"
-    },
-    {
-      new_param: 99, 
-      id: "test3",
-      some_data: "hrmok"
-    },
-  ]);
-
-  // list all objects currently in your datastore
-  console.log("list all objects (return all objects)");
-  my_datastore.list(); 
-
-  // list all objects in SOAPjr format (see separate documentation for SOAPjr API)
-  console.log("list all objects (return all objects in SOAPjr)");
-  my_datastore.list({}, { output_format:"soapjr" }); 
-
-  // view one object
-  console.log("view an object (return one object)");
-  my_datastore.view("test"); // simple
-  my_datastore.view({ id: "test" }); // clear
-  my_datastore.view({ id: "test" }, { output_format:"js" }); // explicit
-
-  // update one object
-  console.log("update an object (return updated fields)");
-  my_datastore.update({
-    data: {
-      new_param: 34, 
-      some_data: "new_data",
-    }, 
-    where: {
-      id: "test",
-    }
-  });
-
-  // search for objects that fuzzy match a pattern
-  console.log("list fuzzy matches (return roughly matching objects)");
-  my_datastore.list({ id: "test" }, { limit: 10 }); 
-
-  // search for objects that exactly match a pattern
-  console.log("list exact matches (return exactly matching objects)");
-  my_datastore.list({ exact: { id: "test2" } }); 
-
-  // delete one object
-  console.log("delete an object (return deleted ids)");
-  my_datastore.delete({ id: "test2" }); 
-
-  // report metadata about this datastore
-  console.log("report overview info (return a summary)");
-  my_datastore.report();
-
-*/
-
-// override this to customise how you want your awe_v8 template to behave
-var V8_CONFIG = {
-  default_id_field: "id",
-  default_output_format: "js",
-  debug: false,
-};
-
-// below here is the template awe_v8 object implementation
-function awe_v8() {
-  var ID_FIELD = "id";
-  try {
-    if (V8_CONFIG.default_id_field !== undefined) {
-      ID_FIELD = V8_CONFIG.default_id_field;
-    }
-  }
-  catch(e) { /* TODO */ }
-  var OUTPUT_FORMAT = "js";
-  try {
-    if (V8_CONFIG.default_output_format !== undefined) {
-      OUTPUT_FORMAT = V8_CONFIG.default_output_format;
-    }
-  }
-  catch(e) { /* TODO */ }
-  var awe_v8_object = new awe_v8_template();
-  var _return = function(return_flag, return_values, errors, output_format) {
-    if (output_format === undefined) {
-      output_format = OUTPUT_FORMAT;
-    }
-    if (output_format == "soapjr") {
-      var return_object = {
-        HEAD: {},
-        BODY: []
-      };
-      if (return_flag) {
-        if (typeof(return_values) === "object" && return_values.length !== undefined) {
-          return_object.BODY = return_values;
-        }
-        else {
-          return_object.BODY = [return_values];
-        }
-        return_object.HEAD.result = 1;
-        return return_object;
-      }
-      else {
-        return_object.HEAD.result = 0;
-        if (errors !== undefined && Object.keys(errors).length) {
-          for (var i in errors) {
-            if (Object.keys(errors[i]).length) {
-              
-              return_object.HEAD.errors[i] = errors[i];
-            }
-          }
-        }
-        return return_object;
-      }
-    }
-    else {
-      if (return_flag) {
-        return return_values;
-      }
-      else {
-        return undefined;
-      }
-    }
-  };
-  function _add(data, io, errors) {
-    if (io == undefined) {
-      throw "io undefined";
-    }
-    if (data[io[ID_FIELD]] !== undefined) {
-      errors.BODY[ID_FIELD] = {
-        code: 500,
-        message: ID_FIELD+" already exists ("+io[ID_FIELD]+")", 
-      };
-      throw ID_FIELD+" already exists ("+io[ID_FIELD]+")";
-    }
-    else {
-      data[io[ID_FIELD]] = io;
-      return io[ID_FIELD];
-    }
-  };
-  function awe_v8_template() { 
-    var data = {};
-    if (V8_CONFIG.debug !== undefined) {
-      this.debug = V8_CONFIG.debug;
-    }
-    else {
-      this.debug = false;
-    }
-    if (V8_CONFIG.debug_verbose !== undefined) {
-      this.debug_verbose = V8_CONFIG.debug;
-    }
-    else {
-      this.debug_verbose = 0;
-    }
-    this.get_data = function(){
-      return data;
-    }
-    
-    this.constructor.prototype.list = function(BODY, HEAD){
-      if (BODY === undefined) { BODY = {}; }
-      if (HEAD === undefined) { HEAD = {}; }
-      var return_values = [];
-      var return_flag = true;
-      var errors = { HEAD:{}, BODY:{} };
-      var output_format = undefined;
-      if (HEAD !== undefined && HEAD.output_format !== undefined) {
-        output_format = HEAD.output_format;
-      }
-      try {
-        var page = 0;
-        var limit = undefined;
-        var order_by = ID_FIELD;
-        var order_type = "alphabetic";
-        var order_direction = "asc";
-        var data_array = [];  
-        for (var i in data) {
-          data_array.push(data[i]);
-        }
-        if (HEAD !== undefined) {
-          if (HEAD.page !== undefined && typeof(HEAD.page) == "number") {
-            page = HEAD.page-1;
-          }
-          if (HEAD.limit !== undefined && typeof(HEAD.limit) == "number") {
-            limit = HEAD.limit;
-          }
-          if (HEAD.order_by !== undefined && typeof(HEAD.order_by) == "string") {
-            order_by = HEAD.order_by;
-          }
-          if (HEAD.order_type !== undefined && HEAD.order_type == "numeric") {
-            order_type = "numeric";
-          }
-          if (HEAD.order_direction !== undefined && HEAD.order_direction == "desc") {
-            order_direction = "desc";
-          }
-        }
-        var sort_function = function(A, B) {
-          var a = undefined;
-          var b = undefined;
-          if (order_type == "alphabetic") {
-            if (A[order_by] !== undefined && typeof(A[order_by]) == "string") {
-              a = A[order_by].toLowerCase();
-            }
-            if (B[order_by] !== undefined && typeof(B[order_by]) == "string") {
-              b = B[order_by].toLowerCase();
-            }
-            if (order_direction == "asc") {
-              if (a == undefined && b !== undefined) {
-                return 0;
-              }
-              else if (a == undefined) {
-                return 1;
-              }
-              else if (b == undefined) {
-                return -1
-              }
-              else {
-                if (a < b) {
-                  return -1;
-                }
-                else if (a > b) {
-                  return 1;
-                }
-                else {
-                  return 0;
-                }
-              }
-            }
-            else {
-              if (a == undefined && b !== undefined) {
-                return 0;
-              }
-              else if (a == undefined) {
-                return -1;
-              }
-              else if (b == undefined) {
-                return 1
-              }
-              else {
-                if (a > b) {
-                  return -1;
-                }
-                else if (a < b) {
-                  return 1;
-                }
-                else {
-                  return 0;
-                }
-              }
-            }
-          }
-          else {
-            if (A[order_by] !== undefined && typeof(A[order_by]) == "number") {
-              a = A[order_by];
-            } 
-            if (B[order_by] !== undefined && typeof(B[order_by]) == "number") {
-              b = B[order_by];
-            } 
-            if (order_direction == "asc") {
-              if (a == undefined && b == undefined) {
-                return 0
-              }
-              else if (a == undefined) {
-                return 1;
-              }
-              else if (b == undefined) {
-                return -1;
-              }
-              else {
-                return a-b; 
-              }
-            }
-            else {
-              if (a == undefined && b == undefined) {
-                return 0
-              }
-              else if (a == undefined) {
-                return 1;
-              }
-              else if (b == undefined) {
-                return -1;
-              }
-              else {
-                return b-a; 
-              }
-            }
-          }
-        };
-        for (var i in data_array) {
-          if (BODY == undefined || BODY.length == 0) {
-            return_values.push(data_array[i]);
-          }
-          else if (BODY !== undefined && BODY.exact !== undefined) {
-            var a = undefined;
-            var b = undefined;
-            var match = 1;
-            for (var m in BODY.exact) {
-              a = data_array[i][m];
-              b = BODY.exact[m];
-              if (a != b) {
-                match = 0;
-              }
-            }
-            if (match) {
-              return_values.push(data_array[i]);
-            }
-          }
-          else {
-            var match = 1;
-            for (var m in BODY) {
-              
-              if (data_array[i][m] !== undefined && typeof(data_array[i][m]) == "string") {
-                a = data_array[i][m].toLowerCase();
-              }
-              else if (typeof(data_array[i][m]) == "number") {
-                a = data_array[i][m];
-              }
-              if (BODY[m] !== undefined && typeof(BODY[m]) == "string") {
-                b = BODY[m].toLowerCase();
-              }
-              else if (typeof(BODY[m]) == "number") {
-                b = BODY[m];
-              }
-              if (typeof(a) == 'string' && typeof(b) == 'string') {
-                var r = a.match(b);
-                if (r == undefined) { 
-                  match = 0;
-                }
-              }
-              else if (typeof(a) == 'number' && typeof(b) == 'number') {
-                if (a != b) {
-                  match = 0;
-                }
-              }
-              else {
-                match = 0;
-              }
-            }
-            if (match) {
-              return_values.push(data_array[i]);
-            }
-          }
-        }
-        return_values = return_values.sort(sort_function);
-        if (limit !== undefined) {
-          var start = limit*page;
-          var end = limit*(page+1);
-          return_values = return_values.slice(start,end);
-        }
-      }
-      catch(e) {
-        this.error_handler(e);
-        return_flag = false;
-      }
-      /* NOTE: commented out to make it more forgiving - maybe move to config
-      if (!(return_values.length > 0)) {
-        return_flag = false;
-        errors.BODY.io = {
-          code: 500,
-          message: "object does not exist",
-        };
-      }
-      */
-      return _return(return_flag, return_values, errors, output_format);
-    };
-
-    this.constructor.prototype.add = function(BODY, HEAD) {
-      if (BODY == undefined) { BODY = {}; }
-      if (HEAD == undefined) { HEAD = {}; }
-      var return_values = [];
-      var return_flag = true;
-      var errors = { HEAD:{}, BODY:{} };
-      var output_format = undefined;
-      if (HEAD !== undefined) {
-        if (HEAD.output_format !== undefined) {
-          output_format = HEAD.output_format;
-        }
-        if (HEAD.replace_all !== undefined && HEAD.replace_all) {
-          data = {};
-        }
-      }
-      try {
-        /* NOTE: commented out to make it more forgiving - maybe move to config
-        if (BODY == undefined) {
-          errors.BODY = {
-            code: 500,
-            message: "BODY object invalid (undefined)",
-          };
-          throw "BODY object invalid (undefined)";
-        }
-        */
-        if (typeof(BODY) == "string") {
-          errors.BODY = {
-            code: 500,
-            message: "BODY object invalid (string)",
-          };
-          throw "BODY object invalid (string)";
-        }
-        if (typeof(BODY) == "number") {
-          errors.BODY = {
-            code: 500,
-            message: "BODY object invalid (number)",
-          };
-          throw "BODY object invalid (number)";
-        }
-        if ((Array.isArray && Array.isArray(BODY)) || (BODY[ID_FIELD] == undefined && BODY.length > 0)) {
-          for (var i in BODY) {
-            var a = _add(data, BODY[i], errors);
-            if (a) {
-              return_values.push(a); // if this fails will it still push something? yes, undefined
-            }
-            else {
-              throw "add failed";
-            }
-          }
-        }
-        else {
-          var a = _add(data, BODY, errors)
-          if (a) {
-              return_values.push(a); // if this fails will it still push something? yes, undefined
-          }
-          else {
-            throw "add failed";
-          }
-        }
-      }
-      catch(e) {
-        this.error_handler(e);
-        return_flag = false;
-      }
-      if (return_values.length == 0) {
-        return _return(return_flag, {}, errors, output_format);
-      }
-      else if (return_values.length == 1) {
-        return _return(return_flag, { id: return_values[0] }, errors, output_format);
-      }
-      else {
-        return _return(return_flag, { id: return_values }, errors, output_format);
-      }
-    };
-
-    this.constructor.prototype.view = function(BODY, HEAD) {
-      if (BODY == undefined) { BODY = {}; }
-      if (HEAD == undefined) { HEAD = {}; }
-      var return_value = undefined;
-      var return_flag = true;
-      var errors = { HEAD:{}, BODY:{} };
-      var output_format = undefined;
-      if (HEAD !== undefined && HEAD.output_format !== undefined) {
-        output_format = HEAD.output_format;
-      }
-      try {
-        if ((typeof(BODY) == "string" || typeof(BODY) == "number") && data[BODY] !== undefined) {
-          return data[BODY].hasOwnProperty('value') ? data[BODY].value : data[BODY];
-        }
-        else if (BODY !== undefined && BODY.id !== undefined && data[BODY.id]) {
-          return_value = data[BODY.id].hasOwnProperty('value') ? data[BODY.id].value : data[BODY.id];
-        }
-        else {
-          errors.BODY.id = {
-            code: 500,
-            message: BODY.id+" does not exist", 
-          };
-          throw BODY.id+" does not exist";
-        }
-      }
-      catch(e) {
-        this.error_handler(e);
-        return_flag = false;
-      }
-      return _return(return_flag, return_value, errors);
-    };
-
-    this.constructor.prototype.update = function(BODY, HEAD) {
-      if (BODY == undefined) { BODY = {}; }
-      if (HEAD == undefined) { HEAD = {}; }
-      var return_values = HEAD.fields_updated || [];
-      var return_flag = true;
-      var errors = { HEAD:{}, BODY:{} };
-      var output_format = undefined;
-      if (HEAD !== undefined && HEAD.output_format !== undefined) {
-        output_format = HEAD.output_format;
-      }
-      try {
-        if (BODY.data == undefined) {
-          errors.BODY.data = {
-            code: 500,
-            message: "missing 'data' clause in BODY object", 
-          };
-          throw "missing 'data' clause in BODY object";
-        }
-        if (BODY.where == undefined) {
-          errors.BODY.where = {
-            code: 500,
-            message: "missing 'where' clause in BODY object", 
-          };
-          throw "missing 'where' clause in BODY object";
-        }
-        if (BODY.where[ID_FIELD] !== undefined) {
-          if (!Array.isArray(BODY.where[ID_FIELD])) {
-            BODY.where[ID_FIELD] = [BODY.where[ID_FIELD]];
-          }
-          var idsLength = BODY.where[ID_FIELD].length;
-
-          if (HEAD.strict) {
-            for (var j = 0; j < idsLength; j++) {
-              if (data[BODY.where[ID_FIELD][j]] == undefined) {
-                errors.BODY[BODY.where[ID_FIELD][j]] = {
-                  code: 500,
-                  message: ID_FIELD+" doesn't exist ("+BODY.where[ID_FIELD][j]+")", 
-                };
-                throw ID_FIELD+" doesn't exist ("+BODY.where[ID_FIELD][j]+")";
-              }
-            }
-          }
-          
-          for (var i in BODY.data) {
-            if (i != ID_FIELD) {
-              for (var j = 0; j < idsLength; j++) {
-                if (data[BODY.where[ID_FIELD][j]] == undefined) {
-                  // no such item!
-                  console.warn('no such item to update!', BODY.where[ID_FIELD][j]);
-                  // continue
-                  var newBODY = {};
-                  newBODY[i] = BODY.data[i];
-                  newBODY[ID_FIELD] = BODY.where[ID_FIELD][j];
-                  this.add(newBODY, HEAD);
-                }
-                // use the setter if available
-                if (data[BODY.where[ID_FIELD][j]]._set_data_value && typeof (data[BODY.where[ID_FIELD][j]]._set_data_value) == 'function') {
-                  data[BODY.where[ID_FIELD][j]]._set_data_value(i, BODY.data[i]);
-                }
-                else {
-                  data[BODY.where[ID_FIELD][j]][i] = BODY.data[i];
-                }
-                return_values.push(i);
-              }
-            }
-          }
-        }
-        else {
-          errors.BODY.where = {
-            code: 500,
-            message: "where."+ID_FIELD+" required", 
-          };
-          throw "where."+ID_FIELD+" required";
-        }
-      }
-      catch(e) {
-        this.error_handler(e);
-        return_flag = false;
-      }
-      return _return(return_flag, { fields_updated: return_values }, errors, output_format);
-    };
-
-    this.constructor.prototype.delete = function(BODY, HEAD) {
-      if (BODY == undefined) { BODY = {}; }
-      if (HEAD == undefined) { HEAD = {}; }
-      var return_values = [];
-      var return_flag = true;
-      var errors = { HEAD:{}, BODY:{} };
-      var output_format = undefined;
-      if (HEAD.output_format !== undefined) {
-        output_format = HEAD.output_format;
-      }
-      try {
-        
-        if (typeof BODY == 'string' || typeof BODY == 'number') {
-          var t = {};
-          t[ID_FIELD] = BODY;
-          BODY = t;
-        }
-        if (typeof(BODY[ID_FIELD]) == "string" || typeof(BODY[ID_FIELD]) == "number") {
-          if (BODY !== undefined && data[BODY[ID_FIELD]] !== undefined) {
-            delete(data[BODY[ID_FIELD]]);
-            return_values.push(BODY[ID_FIELD]);
-          }
-          else {
-            errors.BODY[ID_FIELD] = {
-              code: 500,
-              message: BODY[ID_FIELD]+" does not exist", 
-            };
-            throw BODY[ID_FIELD]+" does not exist";
-          }
-        }
-        else {
-          for (var id in BODY[ID_FIELD]) {
-            if (BODY[ID_FIELD][id] !== undefined && data[BODY[ID_FIELD][id]] !== undefined) {
-              delete(data[BODY[ID_FIELD][id]]);
-              return_values.push(BODY[ID_FIELD][id]);
-            }
-            else {
-              errors.BODY[BODY[ID_FIELD][id]] = {
-                code: 500,
-                message: BODY[ID_FIELD][id]+" does not exist" 
-              };
-              throw BODY[ID_FIELD][id]+" does not exist";
-            }
-          }
-        }
-      }
-      catch(e) {
-        this.error_handler(e);
-        return_flag = false;
-      }
-      if (return_values.length == 0) {
-        return _return(return_flag, {}, errors, output_format);
-      }
-      else if (return_values.length == 1) {
-        return _return(return_flag, { id: return_values[0] }, errors, output_format);
-      }
-      else {
-        return _return(return_flag, { id: return_values }, errors, output_format);
-      }
-    };
-
-    this.constructor.prototype.report = function(BODY, HEAD) {
-      if (BODY == undefined) { BODY = {}; }
-      if (HEAD == undefined) { HEAD = {}; }
-      var return_value = {
-        count: 0,
-        fields: {},
-      };
-      var return_flag = true;
-      var errors = { HEAD:{}, BODY:{} };
-      var output_format = undefined;
-      if (HEAD !== undefined && HEAD.output_format !== undefined) {
-        output_format = HEAD.output_format;
-      }
-      try {
-        if (data == undefined) {
-          errors.HEAD.data = {
-            code: 500,
-            message: "internal data invalid" 
-          };
-          throw "internal data invalid";
-        }
-        for (var i in data) {
-          for (var k in data[i]) {
-            if (return_value.fields[k] == undefined) {
-              return_value.fields[k] = 1;
-            }
-            else {
-              return_value.fields[k]++;
-            }
-          }
-          return_value.count++;
-        }
-      }
-      catch(e) {
-        this.error_handler(e);
-        return_flag = false;
-      }
-      return _return(return_flag, return_value, errors, output_format);
-    };
-
-
-    this.constructor.prototype.error_handler = function(e, debug) {
-      if (debug || this.debug) {
-        if (e.code && e.message) {
-          console.log("ERROR: "+e.code);
-          console.log(e.message);
-        }
-        else {
-          console.log("ERROR");
-          console.log(e);
-        }
-        if (this.debug_verbose > 0) {
-          console.log("CALLER");
-          console.log(arguments.callee.caller);
-        }
-        if (this.debug_verbose > 2) {
-          console.log(arguments.callee.caller.toString());
-        }
-      }
-    };
-    
-    this.constructor.prototype.toString = function() {
-    	return 'awe_v8_object'
-    };
-
-    return this;
-  };
-  return awe_v8_object;
-}
-// END FILE:  awe_v8.js
\ No newline at end of file
diff --git a/js/plugins/StereoEffect.js b/js/plugins/StereoEffect.js
deleted file mode 100644
index a7f3bdc..0000000
--- a/js/plugins/StereoEffect.js
+++ /dev/null
@@ -1,126 +0,0 @@
-/**
- * @author alteredq / http://alteredqualia.com/
- * @authod mrdoob / http://mrdoob.com/
- * @authod arodic / http://aleksandarrodic.com/
- * @authod fonserbc / http://fonserbc.github.io/
- *
- * Off-axis stereoscopic effect based on http://paulbourke.net/stereographics/stereorender/
- */
-
-	
-THREE.StereoEffect = function ( renderer ) {
-
-	var _width, _height;
-
-	var _position = new THREE.Vector3();
-	var _quaternion = new THREE.Quaternion();
-	var _scale = new THREE.Vector3();
-
-	var _cameraL = new THREE.PerspectiveCamera();
-	var _cameraR = new THREE.PerspectiveCamera();
-
-	var _fov;
-	var _outer, _inner, _top, _bottom;
-	var _ndfl, _halfFocalWidth, _halfFocalHeight;
-	var _innerFactor, _outerFactor;
-	
-	// API
-
-	this.separation = 0.8;
-
-	/*
-	 * Distance to the non-parallax or projection plane
-	 */
-	this.focalLength = 15;
-
-	// internals
-
-
-	// initialization
-
-	renderer.autoClear = false;
-	
-	// expose cameras for plugins
-	this.getCameras = function(){
-  	return {
-    	left: _cameraL,
-    	right: _cameraR
-  	}
-	};
-
-	this.setSize = function ( width, height, apply_css ) {
-
-		_width = width / 2;
-		_height = height;
-
-		renderer.setSize( width, height, apply_css );
-	};
-
-	this.render = function ( scene, camera ) {
-
-		scene.updateMatrixWorld();
-
-		if ( camera.parent === undefined ) camera.updateMatrixWorld();
-	
-		camera.matrixWorld.decompose( _position, _quaternion, _scale );
-
-		// Stereo frustum calculation
-
-		// Effective fov of the camera
-		_fov = THREE.Math.radToDeg( 2 * Math.atan( Math.tan( THREE.Math.degToRad( camera.fov ) * 0.5 ) ) );
-
-		_ndfl = camera.near / this.focalLength;
-		_halfFocalHeight = Math.tan( THREE.Math.degToRad( _fov ) * 0.5 ) * this.focalLength;
-		_halfFocalWidth = _halfFocalHeight * 0.5 * camera.aspect;
-
-		_top = _halfFocalHeight * _ndfl;
-		_bottom = -_top;
-		_innerFactor = ( _halfFocalWidth + this.separation / 2.0 ) / ( _halfFocalWidth * 2.0 );
-		_outerFactor = 1.0 - _innerFactor;
-
-		_outer = _halfFocalWidth * 2.0 * _ndfl * _outerFactor;
-		_inner = _halfFocalWidth * 2.0 * _ndfl * _innerFactor;
-
-		// left
-
-		_cameraL.projectionMatrix.makeFrustum(
-			-_outer,
-			_inner,
-			_bottom,
-			_top,
-			camera.near,
-			camera.far
-		);
-
-		_cameraL.position.copy( _position );
-		_cameraL.quaternion.copy( _quaternion );
-		_cameraL.translateX( - this.separation / 2.0 );
-
-		// right
-
-		_cameraR.projectionMatrix.makeFrustum(
-			-_inner,
-			_outer,
-			_bottom,
-			_top,
-			camera.near,
-			camera.far
-		);
-
-		_cameraR.position.copy( _position );
-		_cameraR.quaternion.copy( _quaternion );
-		_cameraR.translateX( this.separation / 2.0 );
-
-		//
-
-		renderer.setViewport( 0, 0, _width * 2, _height );
-		renderer.clear();
-
-		renderer.setViewport( 0, 0, _width, _height );
-		renderer.render( scene, _cameraL );
-
-		renderer.setViewport( _width, 0, _width, _height );
-		renderer.render( scene, _cameraR );
-	};
-
-};
diff --git a/js/plugins/VREffect.js b/js/plugins/VREffect.js
deleted file mode 100644
index 53bab1e..0000000
--- a/js/plugins/VREffect.js
+++ /dev/null
@@ -1,262 +0,0 @@
-/**
- * @author dmarcos / https://github.com/dmarcos
- *
- * It handles stereo rendering
- * If mozGetVRDevices and getVRDevices APIs are not available it gracefuly falls back to a
- * regular renderer
- *
- * The HMD supported is the Oculus DK1 and The Web API doesn't currently allow
- * to query for the display resolution (only the chrome API allows it).
- * The dimensions of the screen are temporarly hardcoded (1280 x 800).
- *
- * For VR mode to work it has to be used with the Oculus enabled builds of Firefox or Chrome:
- *
- * Firefox:
- *
- * http://mozvr.com/downloads.html
- *
- * Chrome builds:
- *
- * https://drive.google.com/a/google.com/folderview?id=0BzudLt22BqGRbW9WTHMtOWMzNjQ&usp=sharing#list
- *
- */
-THREE.VREffect = function ( renderer, done ) {
-
-	var cameraLeft = new THREE.PerspectiveCamera();
-	var cameraRight = new THREE.PerspectiveCamera();
-
-	// expose cameras for plugins
-	this.getCameras = function(){
-  	return {
-    	left: cameraLeft,
-    	right: cameraRight
-  	}
-	};
-	
-	
-	this._renderer = renderer;
-
-	this._init = function() {
-		var self = this;
-		if ( !navigator.mozGetVRDevices && !navigator.getVRDevices ) {
-			if ( done ) {
-				done("Your browser is not VR Ready");
-			}
-			return;
-		}
-		if ( navigator.getVRDevices ) {
-			navigator.getVRDevices().then( gotVRDevices );
-		} else {
-			navigator.mozGetVRDevices( gotVRDevices );
-		}
-		function gotVRDevices( devices ) {
-			var vrHMD;
-			var error;
-			for ( var i = 0; i < devices.length; ++ i ) {
-				if ( devices[i] instanceof HMDVRDevice ) {
-					vrHMD = devices[i];
-					self._vrHMD = vrHMD;
-					self.leftEyeTranslation = vrHMD.getEyeTranslation( "left" );
-					self.rightEyeTranslation = vrHMD.getEyeTranslation( "right" );
-					self.leftEyeFOV = vrHMD.getRecommendedEyeFieldOfView( "left" );
-					self.rightEyeFOV = vrHMD.getRecommendedEyeFieldOfView( "right" );
-					break; // We keep the first we encounter
-				}
-			}
-			if ( done ) {
-				if ( !vrHMD ) {
-					error = 'HMD not available';
-				}
-				done( error );
-			}
-		}
-	};
-
-	this._init();
-
-	this.render = function ( scene, camera ) {
-		var renderer = this._renderer;
-		var vrHMD = this._vrHMD;
-		// VR render mode if HMD is available
-		if ( vrHMD ) {
-			this.renderStereo.apply( this, arguments );
-			return;
-		}
-		// Regular render mode if not HMD
-		if ( scene instanceof Array ) scene = scene[ 0 ];
-		renderer.render.apply( this._renderer, arguments );
-	};
-
-	this.renderStereo = function( scene, camera, renderTarget, forceClear ) {
-
-		var sceneLeft, sceneRight;
-
-		if ( scene instanceof Array ) {
-
-			sceneLeft = scene[ 0 ];
-			sceneRight = scene[ 1 ];
-
-		} else {
-
-			sceneLeft = scene;
-			sceneRight = scene;
-
-		}
-
-		var leftEyeTranslation = this.leftEyeTranslation;
-		var rightEyeTranslation = this.rightEyeTranslation;
-		var renderer = this._renderer;
-		var rendererWidth = renderer.context.drawingBufferWidth;
-		var rendererHeight = renderer.context.drawingBufferHeight;
-		var eyeDivisionLine = rendererWidth / 2;
-
-		renderer.enableScissorTest( true );
-		renderer.clear();
-
-		if ( camera.parent === undefined ) {
-			camera.updateMatrixWorld();
-		}
-
-		cameraLeft.projectionMatrix = this.FovToProjection( this.leftEyeFOV, true, camera.near, camera.far );
-		cameraRight.projectionMatrix = this.FovToProjection( this.rightEyeFOV, true, camera.near, camera.far );
-
-		camera.matrixWorld.decompose( cameraLeft.position, cameraLeft.quaternion, cameraLeft.scale );
-		camera.matrixWorld.decompose( cameraRight.position, cameraRight.quaternion, cameraRight.scale );
-
-		cameraLeft.translateX( leftEyeTranslation.x );
-		cameraRight.translateX( rightEyeTranslation.x );
-
-		// render left eye
-		renderer.setViewport( 0, 0, eyeDivisionLine, rendererHeight );
-		renderer.setScissor( 0, 0, eyeDivisionLine, rendererHeight );
-		renderer.render( sceneLeft, cameraLeft );
-
-		// render right eye
-		renderer.setViewport( eyeDivisionLine, 0, eyeDivisionLine, rendererHeight );
-		renderer.setScissor( eyeDivisionLine, 0, eyeDivisionLine, rendererHeight );
-		renderer.render( sceneRight, cameraRight );
-
-		renderer.enableScissorTest( false );
-
-	};
-
-	this.setSize = function( width, height, resize_canvas ) {
-		renderer.setSize( width, height, resize_canvas );
-	};
-
-	this.setFullScreen = function( enable ) {
-		var renderer = this._renderer;
-		var vrHMD = this._vrHMD;
-		var canvasOriginalSize = this._canvasOriginalSize;
-		if (!vrHMD) {
-			return;
-		}
-		// If state doesn't change we do nothing
-		if ( enable === this._fullScreen ) {
-			return;
-		}
-		this._fullScreen = !!enable;
-
-		// VR Mode disabled
-		if ( !enable ) {
-			// Restores canvas original size
-			renderer.setSize( canvasOriginalSize.width, canvasOriginalSize.height, false );
-			return;
-		}
-		// VR Mode enabled
-		this._canvasOriginalSize = {
-			width: renderer.domElement.width,
-			height: renderer.domElement.height
-		};
-		// Hardcoded Rift display size
-		renderer.setSize( 1280, 800, false );
-		this.startFullscreen();
-	};
-
-	this.startFullscreen = function() {
-		var self = this;
-		var renderer = this._renderer;
-		var vrHMD = this._vrHMD;
-		var canvas = renderer.domElement;
-		var fullScreenChange =
-			canvas.mozRequestFullScreen ? 'mozfullscreenchange' : 'webkitfullscreenchange';
-
-		document.addEventListener( fullScreenChange, onFullScreenChanged, false );
-		function onFullScreenChanged() {
-			if ( !document.mozFullScreenElement && !document.webkitFullscreenElement ) {
-				self.setFullScreen( false );
-			}
-		}
-		if ( canvas.mozRequestFullScreen ) {
-			canvas.mozRequestFullScreen( { vrDisplay: vrHMD } );
-		} else if ( canvas.webkitRequestFullscreen ) {
-			canvas.webkitRequestFullscreen( { vrDisplay: vrHMD } );
-		}
-	};
-
-	this.FovToNDCScaleOffset = function( fov ) {
-		var pxscale = 2.0 / (fov.leftTan + fov.rightTan);
-		var pxoffset = (fov.leftTan - fov.rightTan) * pxscale * 0.5;
-		var pyscale = 2.0 / (fov.upTan + fov.downTan);
-		var pyoffset = (fov.upTan - fov.downTan) * pyscale * 0.5;
-		return { scale: [ pxscale, pyscale ], offset: [ pxoffset, pyoffset ] };
-	};
-
-	this.FovPortToProjection = function( fov, rightHanded /* = true */, zNear /* = 0.01 */, zFar /* = 10000.0 */ )
-	{
-		rightHanded = rightHanded === undefined ? true : rightHanded;
-		zNear = zNear === undefined ? 0.01 : zNear;
-		zFar = zFar === undefined ? 10000.0 : zFar;
-
-		var handednessScale = rightHanded ? -1.0 : 1.0;
-
-		// start with an identity matrix
-		var mobj = new THREE.Matrix4();
-		var m = mobj.elements;
-
-		// and with scale/offset info for normalized device coords
-		var scaleAndOffset = this.FovToNDCScaleOffset(fov);
-
-		// X result, map clip edges to [-w,+w]
-		m[0 * 4 + 0] = scaleAndOffset.scale[0];
-		m[0 * 4 + 1] = 0.0;
-		m[0 * 4 + 2] = scaleAndOffset.offset[0] * handednessScale;
-		m[0 * 4 + 3] = 0.0;
-
-		// Y result, map clip edges to [-w,+w]
-		// Y offset is negated because this proj matrix transforms from world coords with Y=up,
-		// but the NDC scaling has Y=down (thanks D3D?)
-		m[1 * 4 + 0] = 0.0;
-		m[1 * 4 + 1] = scaleAndOffset.scale[1];
-		m[1 * 4 + 2] = -scaleAndOffset.offset[1] * handednessScale;
-		m[1 * 4 + 3] = 0.0;
-
-		// Z result (up to the app)
-		m[2 * 4 + 0] = 0.0;
-		m[2 * 4 + 1] = 0.0;
-		m[2 * 4 + 2] = zFar / (zNear - zFar) * -handednessScale;
-		m[2 * 4 + 3] = (zFar * zNear) / (zNear - zFar);
-
-		// W result (= Z in)
-		m[3 * 4 + 0] = 0.0;
-		m[3 * 4 + 1] = 0.0;
-		m[3 * 4 + 2] = handednessScale;
-		m[3 * 4 + 3] = 0.0;
-
-		mobj.transpose();
-
-		return mobj;
-	};
-
-	this.FovToProjection = function( fov, rightHanded /* = true */, zNear /* = 0.01 */, zFar /* = 10000.0 */ )
-	{
-		var fovPort = {
-			upTan: Math.tan(fov.upDegrees * Math.PI / 180.0),
-			downTan: Math.tan(fov.downDegrees * Math.PI / 180.0),
-			leftTan: Math.tan(fov.leftDegrees * Math.PI / 180.0),
-			rightTan: Math.tan(fov.rightDegrees * Math.PI / 180.0)
-		};
-		return this.FovPortToProjection(fovPort, rightHanded, zNear, zFar);
-	};
-
-};
diff --git a/js/plugins/awe-standard-object_clicked.js b/js/plugins/awe-standard-object_clicked.js
deleted file mode 100755
index 3bacc35..0000000
--- a/js/plugins/awe-standard-object_clicked.js
+++ /dev/null
@@ -1,80 +0,0 @@
-(function(awe) {
-
-  var projector,
-    ray,
-    camera,
-    canvas;
-  
-  var _ready = false;
-  var _enabled = false;
-  
-	awe.plugins.add([{
-		id: 'object_clicked',
-    auto_register: true,
-    enable: function(){
-      _enabled = true;
-    },
-    disable: function(){
-      _enabled = false;
-    },
-		register: function(){
-			awe.events.add({
-				id: 'click',
-				capabilities: ['webgl'],
-				register: function(handler) {
-					window.addEventListener('click', handler, false);
-				},
-				unregister: function(handler){
-					window.removeEventListener('click', handler, false);
-				},
-				handler: function(e) {
-  				console.log(_enabled, _ready)
-					if (!_enabled) {
-  					console.log('click plugin disabled');
-  					return;
-					}
-					if (!_ready) {
-            projector = new THREE.Projector();
-            ray = new THREE.Raycaster();
-            camera = awe.pov().get_mesh();
-            canvas = awe.renderer().get_canvas();
-            _ready = true;
-					}
-          var settings = awe.util.get_settings('click_handling');
-          if (settings.click_handling === undefined || settings.click_handling == true) {
-            
-            var x = (e.clientX/canvas.clientWidth) * 2 - 1;
-            var y = -(e.clientY/canvas.clientHeight) * 2 + 1;
-            var mouse_vector = new THREE.Vector3(x, y, 1);
-            mouse_vector.unproject(camera); 
-            var direction = mouse_vector.sub(camera.position).normalize();
-            ray.set(camera.position, direction);
-            var intersects = ray.intersectObjects(awe.projections.list({ type:'clickable' }), true);
-            if (intersects.length) {
-              var mesh = _get_clicked_projection(intersects[0].object);
-              if (mesh && mesh.projection_id) {
-                intersects[0].projection_id = mesh.projection_id;
-                var event = new CustomEvent('object_clicked', { detail:intersects[0] });
-                window.dispatchEvent(event);
-              }
-            }
-          }
-				}
-			});
-		},
-		unregister: function(){
-			awe.events.delete('click');
-		}
-	}]);
-  function _get_clicked_projection(mesh) {
-    if (mesh.projection_id == undefined) {
-      if (mesh.parent == undefined) {
-        return undefined;
-      } else {
-        return _get_clicked_projection(mesh.parent);
-      }
-    } else {
-      return mesh;
-    }
-  }
-})(window.awe);
diff --git a/js/plugins/awe-standard-object_clicked_or_focused.js b/js/plugins/awe-standard-object_clicked_or_focused.js
deleted file mode 100644
index d53b6f5..0000000
--- a/js/plugins/awe-standard-object_clicked_or_focused.js
+++ /dev/null
@@ -1,311 +0,0 @@
-
-;(function(awe) {
-
-  var projector,
-    raycaster,
-    main_camera,
-    canvas;
-  
-  var _ready = false;
-  var _enabled = false;
-  
-  var _right_clicked = false;
-
-  var stereo_plugin;
-  var avg_dev;
-  var precision = 4;
-  var orientation_diff = 0.1,
-      last_alpha = [], last_beta = [], last_gamma = [], max_values = 10, threshold = 0.2;
-  
-  
-  // Programmer: Larry Battle
-  // Date: Mar 06, 2011
-  // Purpose: Calculate standard deviation, variance, and average among an array of numbers.
-  var isArray = function (obj) {
-    return Object.prototype.toString.call(obj) === "[object Array]";
-  },
-  getNumWithSetDec = function( num, numOfDec ){
-    var pow10s = Math.pow( 10, numOfDec || 0 );
-    return ( numOfDec ) ? Math.round( pow10s * num ) / pow10s : num;
-  },
-  getAverageFromNumArr = function( numArr, numOfDec ){
-    if( !isArray( numArr ) ){ return false;    }
-    var i = numArr.length,
-        sum = 0;
-    while( i-- ){
-      sum += numArr[ i ];
-    }
-    return getNumWithSetDec( (sum / numArr.length ), numOfDec );
-  },
-  getVariance = function( numArr, numOfDec ){
-    if( !isArray(numArr) ){ return false; }
-    var avg = getAverageFromNumArr( numArr, numOfDec ),
-        i = numArr.length,
-        v = 0;
- 
-    while( i-- ){
-      v += Math.pow( (numArr[ i ] - avg), 2 );
-    }
-    v /= (numArr.length-1);
-    return getNumWithSetDec( v, numOfDec );
-  },
-  getStandardDeviation = function( numArr, numOfDec ){
-    if( !isArray(numArr) ){ return false; }
-    var stdDev = Math.sqrt( getVariance( numArr, numOfDec ) );
-    return getNumWithSetDec( stdDev, numOfDec );
-  };
-  
-  var mouse_down_timer;
-  var last_mouseup_was_click = false;
-  var click_threshold = 200; // [ms] delta between mousedown and mouseup that constitutes a click
-  function _mousedown(is_mouse_down, e){
-    if (is_mouse_down) {
-      mouse_down_timer = Date.now();
-    }
-    else {
-      var delta = Date.now() - mouse_down_timer;
-      if (delta < click_threshold) {
-        last_mouseup_was_click = true;
-      }
-      else {
-        last_mouseup_was_click = false;
-      }
-    }
-  }
-  
-  function is_stereo(){
-    try {
-      var view_count = awe.settings.view('view_count') ? awe.settings.view('view_count').value() : 'mono';
-      return (view_count == 'stereo' && stereo_plugin && stereo_plugin.enabled);
-    }
-    catch(e) { console.warn('object-focused plugin is_stereo()', e); }
-    return false
-  }
-  
-  function setup() {
-    projector = new THREE.Projector();
-    raycaster = new THREE.Raycaster();
-    main_camera = awe.pov().get_mesh();
-    stereo_plugin = awe.plugins.view('render_effects');
-    _ready = true;
-  }
-
-  function _get_clicked_projection(mesh) {
-    if (mesh.projection_id == undefined) {
-      if (mesh.parent == undefined) {
-        return undefined;
-      } else {
-        return _get_clicked_projection(mesh.parent);
-      }
-    } else {
-      return mesh;
-    }
-  }
-  
-  function _click(x,y,camera, right_click){
-    if (!last_mouseup_was_click) { return; }
-    
-    var mouse_x = (x/canvas.clientWidth) * 2 - 1;
-    var mouse_y = -(y/canvas.clientHeight) * 2 + 1;
-    var camera_position = camera.getWorldPosition();
-    var mouse_vector = new THREE.Vector3(mouse_x, mouse_y, 1);
-    mouse_vector.unproject(camera); 
-    var direction = mouse_vector.sub(camera_position).normalize();
-    raycaster.set(camera_position, direction);
-    var intersects = raycaster.intersectObjects(awe.projections.list({ type:'clickable' }), true);
-    console.log(intersects.length)
-    if (intersects.length) {
-      var mesh = _get_clicked_projection(intersects[0].object);
-      if (mesh && mesh.projection_id) {
-        intersects[0].projection_id = mesh.projection_id;
-        var event_name = right_click ? 'object_right_clicked' : 'object_clicked';
-        var event = new CustomEvent(event_name, { detail:intersects[0] });
-        window.dispatchEvent(event);
-        return;
-      }
-    }
-    var event_name = right_click ? 'scene_right_clicked' : 'scene_clicked';
-    var event = new CustomEvent(event_name, { detail:intersects[0] });
-    window.dispatchEvent(event);
-  }
-  
-	awe.plugins.add([{
-		id: 'object_clicked',
-    capabilities: ['webgl'],
-    auto_register: false,
-    enable: function(){
-      _enabled = true;
-    },
-    disable: function(){
-      _enabled = false;
-    },
-		register: function(){
-  		canvas = awe.renderer().get_canvas();
-			awe.events.add([
-  			{
-    			id: 'object_clicked_gyro',
-  				capabilities: ['webgl', 'gyro'],
-  				register: function(handler) {
-  					window.addEventListener('deviceorientation', handler, false);
-  				},
-  				unregister: function(handler){
-  					window.removeEventListener('deviceorientation', handler, false);
-  				},
-  				handler: function(event) {
-        				
-  					if (!_enabled) {
-    					return;
-  					}
-    				if (!is_stereo()) {
-      			  return;
-      		  }
-            last_alpha.unshift(event.alpha);
-            last_beta.unshift(event.beta);
-            last_gamma.unshift(event.gamma);
-            if (last_alpha.length > max_values) {
-              last_alpha.pop();
-              last_beta.pop();
-              last_gamma.pop();
-            }
-            var alpha_dev = getStandardDeviation(last_alpha, precision);
-            var beta_dev = getStandardDeviation(last_beta, precision);
-            var gamma_dev = getStandardDeviation(last_gamma, precision);
-            avg_dev = (alpha_dev+beta_dev+gamma_dev) / 3;
-            
-  				}
-  			},
-
-			  {
-  				id: 'object_clicked_tick',
-  				capabilities: ['webgl', 'gyro'],
-  				register: function(handler) {
-  					window.addEventListener('tick', handler, false);
-  				},
-  				unregister: function(handler){
-  					window.removeEventListener('tick', handler, false);
-  				},
-  				handler: function(e) {
-  					if (!_enabled) {
-    					return;
-  					}
-    				if (!_ready) {
-    					setup();
-    				}
-    				if (!is_stereo()) {
-      			  return;
-      		  }
-					
-          	if (avg_dev && avg_dev < threshold ) {
-              // still
-              var x = e.clientX,
-                y = e.clientY;
-              if (is_stereo()) {
-                var cameras = stereo_plugin.get_stereo_cameras();
-                var camera;
-                
-                if (x > canvas.clientWidth/2) {
-                  // right viewport half
-                  camera = cameras.right;
-                  x -= canvas.clientWidth/2;
-                }
-                else {
-                  // left viewport half
-                  camera = cameras.left;
-                }
-                x *= 2;
-                // perhaps add a timeout here
-                _click(canvas.clientWidth/2, canvas.clientHeight/2, camera);
-              }
-            }
-            else {
-              // shaking 
-            }
-          }
-  			},
-			  {
-  				id: 'object_clicked_mouseup',
-  				capabilities: ['webgl'],
-  				register: function(handler) {
-  					canvas.addEventListener('mouseup', handler, false);
-  				},
-  				unregister: function(handler){
-  					canvas.removeEventListener('mouseup', handler, false);
-  				},
-  				handler: function(e) {
-    				_right_clicked = (e.which == 3);
-    				_mousedown(false);
-  				}
-  			},
-			  {
-  				id: 'object_clicked_mousedown',
-  				capabilities: ['webgl'],
-  				register: function(handler) {
-  					canvas.addEventListener('mousedown', handler, false);
-  				},
-  				unregister: function(handler){
-  					canvas.removeEventListener('mousedown', handler, false);
-  				},
-  				handler: function(e) {
-    				_right_clicked = false;
-    				_mousedown(true);
-  				}
-  			},
-			  {
-  				id: 'object_clicked',
-  				capabilities: ['webgl'],
-  				register: function(handler) {
-  					canvas.addEventListener('contextmenu', handler, false);
-  					canvas.addEventListener('click', handler, false);
-  				},
-  				unregister: function(handler){
-  					canvas.removeEventListener('contextmenu', handler, false);
-  					canvas.removeEventListener('click', handler, false);
-  				},
-  				handler: function(e) {
-    				if (!_enabled) {
-    					console.log('click plugin disabled');
-    					return;
-  					}
-  					if (!_ready) {
-    					setup();
-  					}
-            var settings = awe.util.get_settings('click_handling');
-            if (settings.click_handling === undefined || settings.click_handling == true) {
-              var x = e.clientX,
-                y = e.clientY,
-                camera;
-              if (is_stereo()) {
-//               var view_count = awe.settings.view('view_count') ? awe.settings.view('view_count').value() : 'mono';
-//               if (view_count == 'stereo' && stereo_plugin && stereo_plugin.enabled) {
-                var cameras = stereo_plugin.get_stereo_cameras();
-                
-                if (x > canvas.clientWidth/2) {
-                  // right viewport half
-                  camera = cameras.right;
-                  x -= canvas.clientWidth/2;
-                }
-                else {
-                  // left viewport half
-                  camera = cameras.left;
-                }
-                x *= 2;
-              }
-              else {
-                camera = main_camera;
-              }
-              e.preventDefault();
-              _click(x, y, camera, e.type == 'contextmenu');
-              
-            }
-  				}
-  			},
-
-			]);
-		},
-		unregister: function(){
-			awe.events.delete('object_clicked_gyro');
-			awe.events.delete('object_clicked_tick');
-			awe.events.delete('object_clicked_mono');
-		}
-	}]);
-})(window.awe);
diff --git a/js/plugins/awe-standard-object_focused.js b/js/plugins/awe-standard-object_focused.js
deleted file mode 100755
index ba41f73..0000000
--- a/js/plugins/awe-standard-object_focused.js
+++ /dev/null
@@ -1,252 +0,0 @@
-(function(awe) {
-
-  var projector,
-    raycaster,
-    main_camera,
-    canvas;
-  
-  var _ready = false;
-  var _enabled = false;
-
-  var stereo_plugin;
-  var avg_dev;
-  var precision = 4;
-  var orientation_diff = 0.1,
-      last_alpha = [], last_beta = [], last_gamma = [], max_values = 10, threshold = 0.2;
-  
-  
-  // Programmer: Larry Battle
-  // Date: Mar 06, 2011
-  // Purpose: Calculate standard deviation, variance, and average among an array of numbers.
-  var isArray = function (obj) {
-    return Object.prototype.toString.call(obj) === "[object Array]";
-  },
-  getNumWithSetDec = function( num, numOfDec ){
-    var pow10s = Math.pow( 10, numOfDec || 0 );
-    return ( numOfDec ) ? Math.round( pow10s * num ) / pow10s : num;
-  },
-  getAverageFromNumArr = function( numArr, numOfDec ){
-    if( !isArray( numArr ) ){ return false;    }
-    var i = numArr.length,
-        sum = 0;
-    while( i-- ){
-      sum += numArr[ i ];
-    }
-    return getNumWithSetDec( (sum / numArr.length ), numOfDec );
-  },
-  getVariance = function( numArr, numOfDec ){
-    if( !isArray(numArr) ){ return false; }
-    var avg = getAverageFromNumArr( numArr, numOfDec ),
-        i = numArr.length,
-        v = 0;
- 
-    while( i-- ){
-      v += Math.pow( (numArr[ i ] - avg), 2 );
-    }
-    v /= (numArr.length-1);
-    return getNumWithSetDec( v, numOfDec );
-  },
-  getStandardDeviation = function( numArr, numOfDec ){
-    if( !isArray(numArr) ){ return false; }
-    var stdDev = Math.sqrt( getVariance( numArr, numOfDec ) );
-    return getNumWithSetDec( stdDev, numOfDec );
-  };
-  
-  function is_stereo(){
-    try {
-      var view_count = awe.settings.view('view_count') ? awe.settings.view('view_count').value() : 'mono';
-      return (view_count == 'stereo' && stereo_plugin && stereo_plugin.enabled);
-    }
-    catch(e) { console.warn('object-focused plugin is_stereo()'e); }
-    return false
-  }
-  
-  function setup() {
-    projector = new THREE.Projector();
-    raycaster = new THREE.Raycaster();
-    main_camera = awe.pov().get_mesh();
-    canvas = awe.renderer().get_canvas();
-    stereo_plugin = awe.plugins.view('render_effects');
-    _ready = true;
-  }
-
-  function _get_clicked_projection(mesh) {
-    if (mesh.projection_id == undefined) {
-      if (mesh.parent == undefined) {
-        return undefined;
-      } else {
-        return _get_clicked_projection(mesh.parent);
-      }
-    } else {
-      return mesh;
-    }
-  }
-  
-  function _click(x,y,camera){
-
-    var mouse_x = (x/canvas.clientWidth) * 2 - 1;
-    var mouse_y = -(y/canvas.clientHeight) * 2 + 1;
-    var camera_position = camera.getWorldPosition();
-    var mouse_vector = new THREE.Vector3(mouse_x, mouse_y, 1);
-    mouse_vector.unproject(camera); 
-    var direction = mouse_vector.sub(camera_position).normalize();
-    raycaster.set(camera_position, direction);
-    var intersects = raycaster.intersectObjects(awe.projections.list({ type:'clickable' }), true);
-    if (intersects.length) {
-      var mesh = _get_clicked_projection(intersects[0].object);
-      if (mesh && mesh.projection_id) {console.log('clicked', mesh.projection_id)
-        intersects[0].projection_id = mesh.projection_id;
-        var event = new CustomEvent('object_clicked', { detail:intersects[0] });
-        window.dispatchEvent(event);
-      }
-    }
-  }
-  
-	awe.plugins.add([{
-		id: 'object_clicked',
-    capabilities: ['webgl'],
-    auto_register: true,
-    enable: function(){
-      _enabled = true;
-    },
-    disable: function(){
-      _enabled = false;
-    },
-		register: function(){
-			awe.events.add([
-  			{
-    			id: 'object_clicked_gyro',
-  				capabilities: ['webgl', 'gyro'],
-  				register: function(handler) {
-  					window.addEventListener('deviceorientation', handler, false);
-  				},
-  				unregister: function(handler){
-  					window.removeEventListener('deviceorientation', handler, false);
-  				},
-  				handler: function(event) {
-        				
-  					if (!_enabled) {
-    					return;
-  					}
-    				if (!is_stereo()) {
-      			  return;
-      		  }
-            last_alpha.unshift(event.alpha);
-            last_beta.unshift(event.beta);
-            last_gamma.unshift(event.gamma);
-            if (last_alpha.length > max_values) {
-              last_alpha.pop();
-              last_beta.pop();
-              last_gamma.pop();
-            }
-            var alpha_dev = getStandardDeviation(last_alpha, precision);
-            var beta_dev = getStandardDeviation(last_beta, precision);
-            var gamma_dev = getStandardDeviation(last_gamma, precision);
-            avg_dev = (alpha_dev+beta_dev+gamma_dev) / 3;
-            
-  				}
-  			},
-
-			  {
-  				id: 'object_clicked_tick',
-  				capabilities: ['webgl', 'gyro'],
-  				register: function(handler) {
-  					window.addEventListener('tick', handler, false);
-  				},
-  				unregister: function(handler){
-  					window.removeEventListener('tick', handler, false);
-  				},
-  				handler: function(e) {
-  					if (!_enabled) {
-    					return;
-  					}
-    				if (!_ready) {
-    					setup();
-    				}
-    				if (!is_stereo()) {
-      			  return;
-      		  }
-					
-          	if (avg_dev && avg_dev < threshold ) {
-              // still
-              var x = e.clientX,
-                y = e.clientY;
-              if (is_stereo()) {
-                var cameras = stereo_plugin.get_stereo_cameras();
-                var camera;
-                
-                if (x > canvas.clientWidth/2) {
-                  // right viewport half
-                  camera = cameras.right;
-                  x -= canvas.clientWidth/2;
-                }
-                else {
-                  // left viewport half
-                  camera = cameras.left;
-                }
-                x *= 2;
-                // perhaps add a timeout here
-                _click(canvas.clientWidth/2, canvas.clientHeight/2, camera);
-              }
-            }
-            else {
-              // shaking 
-            }
-          }
-  			},
-			  {
-  				id: 'object_clicked',
-  				capabilities: ['webgl'],
-  				register: function(handler) {
-  					window.addEventListener('click', handler, false);
-  				},
-  				unregister: function(handler){
-  					window.removeEventListener('click', handler, false);
-  				},
-  				handler: function(e) {
-  					if (!_enabled) {
-    					console.log('click plugin disabled');
-    					return;
-  					}
-  					if (!_ready) {
-    					setup();
-  					}
-            var settings = awe.util.get_settings('click_handling');
-            if (settings.click_handling === undefined || settings.click_handling == true) {
-              var x = e.clientX,
-                y = e.clientY,
-                camera;
-              if (is_stereo()) {
-//               var view_count = awe.settings.view('view_count') ? awe.settings.view('view_count').value() : 'mono';
-//               if (view_count == 'stereo' && stereo_plugin && stereo_plugin.enabled) {
-                var cameras = stereo_plugin.get_stereo_cameras();
-                
-                if (x > canvas.clientWidth/2) {
-                  // right viewport half
-                  camera = cameras.right;
-                  x -= canvas.clientWidth/2;
-                }
-                else {
-                  // left viewport half
-                  camera = cameras.left;
-                }
-                x *= 2;
-              }
-              else {
-                camera = main_camera;
-              }
-              _click(x, y, camera);
-              
-            }
-  				}
-  			}
-
-			]);
-		},
-		unregister: function(){
-			awe.events.delete('object_clicked_gyro');
-			awe.events.delete('object_clicked_tick');
-			awe.events.delete('object_clicked_mono');
-		}
-	}]);
-})(window.awe);
diff --git a/js/plugins/awe.rendering_effects.js b/js/plugins/awe.rendering_effects.js
deleted file mode 100644
index 26504ad..0000000
--- a/js/plugins/awe.rendering_effects.js
+++ /dev/null
@@ -1,414 +0,0 @@
-
-// var DEBUG = true; 
-
-;(function(awe){
-  
-  if (!awe) {
-    throw 'awe library not included';
-    return;
-  }
-
-  var old_renderers_add,
-    old_render,
-    old_resize_canvas,
-    stereo_effect,
-    vr_effect,
-    enabled = false,
-    vr_effect_supported = true,
-    vs, 
-    video_element,
-    camerastream_projection_id = 'ar_camerastream_projection';
-    
-  var adapt_view_mode, resize_video;
-  
-  var capabilities = awe.util.get_capabilities('gum');
-  
-  function is_stream_ready(){
-    var vs = awe.video_stream();
-    if (vs) {
-      video_element = vs.get_video_element();
-      return vs.is_stream_ready();
-    }
-    return false;
-
-  }
-  awe.plugins.add([{
-    id: 'render_effects',
-    capabilities: ['webgl'], // gum ?
-    auto_register: true,
-    register: function(plugin_data){
-      
-      old_settings_update = awe.settings.update;
-      old_renderers_add = awe.renderers.add;
-      old_render = awe.render;
-      old_resize_canvas = awe.resize_canvas;
-      old_pov_value_updated = awe.povs._item_constructor.prototype._values_updated;
-      
-      awe.povs._item_constructor.prototype._values_updated = function(){
-        old_pov_value_updated.call(this, arguments);
-        if (!capabilities.gum && awe.projections.view(camerastream_projection_id)) {
-          awe.projections.update({
-            data: {
-              position: awe.pov().position
-            },
-            where: {
-              id: camerastream_projection_id
-            }
-          });
-        }
-      };
-      
-      awe.resize_canvas = function(force) {
-        
-        var renderer = awe.renderer(),
-          awe_canvas = renderer.get_canvas(),
-          pov = awe.pov(),
-          width = awe_canvas.clientWidth,
-          height = awe_canvas.clientHeight,
-          aspect = width / height;
-
-        
-        function resize_renderer(){
-          renderer.set_size(width, height, false);
-          resize_video();
-          awe.scene_needs_rendering = 1;
-          
-          var event = new CustomEvent('renderer_resized');
-          window.dispatchEvent(event);
-        }
-        
-        if (awe_canvas.width != width || awe_canvas.height != height || force) {
-          
-          pov.set_aspect(aspect);
-          pov.update_projection_matrix();
-          
-          var view_count = awe.settings.view('view_count') ? awe.settings.view('view_count').value() : 'mono';
-          if (view_count == 'stereo') {
-            if (vr_effect_supported) {
-              vr_effect.setSize(width, height, false);
-            }
-            else if (stereo_effect) {
-              var factor = 1; //window.devicePixelRatio;
-              stereo_effect.setSize(width*factor, height*factor, false);
-            }
-            resize_renderer();
-            // holy shmoly - ios webgl is not applying these changes unless they happen a teeny bit later than the stereo
-            requestAnimationFrame(function(){
-              requestAnimationFrame(resize_renderer);
-            });
-          }
-          else {
-            resize_renderer();
-          }
-        }        
-      };
-      
-      resize_video = function(){
-        if (!capabilities.gum) {
-          console.warn('Your device does not support getUserMedia');
-          return;
-        }
-        if (!is_stream_ready()){
-          return;
-        }
-        if (!awe.projections.view(camerastream_projection_id)) {
-          return;
-        }
-        
-        var pov_mesh = awe.pov().get_mesh(),
-          scale_y = (Math.tan((pov_mesh.fov*Math.PI/180)/2) * pov_mesh.far) * 2,
-          scale_x = pov_mesh.aspect * scale_y,
-          video_aspect = video_element.videoWidth / video_element.videoHeight,
-          new_x, 
-          new_y;
-          
-        if (pov_mesh.aspect > video_aspect) {
-          new_x = scale_x;
-          new_y = new_x / video_aspect;
-        }
-        else {
-          new_y = scale_y;
-          new_x = video_aspect * new_y;
-        }
-        
-          
-        awe.projections.update({
-          data: {
-            scale: { x: new_x, y: new_y }
-          },
-          where: { id: camerastream_projection_id }
-        });
-      }
-
-      
-      adapt_view_mode = function (effect) {
-        if (!enabled) { return; }
-        if (effect == 'ar') {
-          
-          if (!capabilities.gum) {
-            console.warn('Your device does not support getUserMedia');
-//            return;
-          }
-          // add camera stream projection (if one doesn't exist), attached to pov() and at pov.far+1
-          var camerastream_projection = awe.projections.view(camerastream_projection_id);
-          if (camerastream_projection) {
-            camerastream_projection.update({
-              visible: true
-            });
-            camerastream_projection.play_video_texture();
-            resize_video();
-            return;
-          }
-          // add and play camera stream if not playing yet
-          
-          var reset_camerastream_projection = function(){
-            awe.events.delete('render_effects_camerastream_error');
-            if (awe.projections.view(camerastream_projection_id)) {
-              awe.projections.delete(camerastream_projection_id)
-              add_camerastream_projection();
-            }
-          };
-          
-          var add_camerastream_projection = function(){
-            var pov = awe.pov();
-            var settings = awe.util.get_settings('camerastream_poster');
-            var scale_y = (Math.tan(pov.fov/2) * pov.far),
-              scale_x = pov.aspect * scale_y;
-            
-            var geometry, material, texture, position, scale, parent;
-            
-            material = { 
-              type: 'phong',
-              color: 0xFFFFFF,
-            };
-            
-            if (capabilities.gum && !awe.gum_denied) {
-              // camerastream plane with poster fallback
-              geometry = {
-                shape:'plane',
-                width: 1,
-                height: 1 
-              };
-              texture = {
-                color: 0xFFFFFF,
-                path: 'camerastream',
-                poster: settings.camerastream_poster
-              };
-              position = {
-                x: 0,
-                y: 0,
-                z: -pov.far + 1
-              };
-              scale = {
-                x: scale_x,
-                y: scale_y,
-                z: 1
-              };
-              parent = { parent: { object_id: 'default', object_type: 'pov'} }
-            }
-            else {
-              // poster sphere
-              geometry = {
-                shape:'sphere',
-                widthSegments: 50,
-                heightSegments: 20,
-                radius: pov.far-1
-              };
-              texture = {
-                color: 0xFFFFFF,
-                path: settings.camerastream_poster,
-              };
-              position = pov.position;
-              scale = {
-                x: 1,
-                y: 1,
-                z: 1
-              };
-              parent = { parent: { object_id: 'default', object_type: 'scene'} }
-            }
-            
-            awe.projections.add({
-              id: camerastream_projection_id,
-              geometry: geometry,
-              material: material,
-              texture: texture,
-              position: position,
-              scale: scale,
-              not_clickable: 1
-            }, parent);
-          };
-          
-          var attach_camerastream_projection = function(){
-            
-            awe.events.delete('render_effects_camerastream');
-            vs = awe.video_stream();
-            if (!vs) {
-              return;
-            }
-            video_element = vs.get_video_element();
-            
-            if (video_element && video_element.readyState != video_element.HAVE_NOTHING) {
-              resize_video();
-            }
-            else {
-              video_element.addEventListener('loadedmetadata', resize_video);
-            }
-          };
-
-          add_camerastream_projection();
-          
-          if (is_stream_ready()) {
-            attach_camerastream_projection();
-            return;
-          }
-          
-          if (!awe.events.view('render_effects_camerastream') && capabilities.gum) {
-            awe.events.add([
-              {
-                id: 'render_effects_camerastream',
-                register: function(handler){
-                  window.addEventListener('gum_ready', handler);
-                },
-                unregister: function(handler){
-                  window.removeEventListener('gum_ready', handler);
-                },
-                handler: function(e){
-                  attach_camerastream_projection();
-                }
-              },
-              {
-                id: 'render_effects_camerastream_error',
-                register: function(handler){
-                  window.addEventListener('gum_error', handler);
-                },
-                unregister: function(handler){
-                  window.removeEventListener('gum_error', handler);
-                },
-                handler: function(e){
-                //  reset_camerastream_projection();
-                }
-              }
-            ]);
-          }
-
-          
-          if (!awe.video_stream()) {
-            awe.setup_stream();
-          }
-        }
-        else if (awe.projections.view(camerastream_projection_id)) {
-          // hide camera stream poi only if added by adapt_view_mode()
-          // other video stream pois / video elements should keep on playing.
-          awe.projections.update({
-            data: {
-              visible: false
-            },
-            where: { id: camerastream_projection_id }
-          });
-        }
-      }
-      
-      awe.settings.update = function(BODY, HEAD) {
-        old_settings_update.call(this, BODY, HEAD);
-        
-        if (BODY.where.id && (BODY.where.id == 'view_mode' || (BODY.where.includes && BODY.where.id.includes('view_mode'))) ) {
-          var view_mode = awe.settings.view('view_mode') ? awe.settings.view('view_mode').value() : 'vr';
-          adapt_view_mode(view_mode);
-          
-          var event = new CustomEvent('view_mode_changed', {detail: view_mode});
-          window.dispatchEvent(event);
-        }
-        if (BODY.where.id && (BODY.where.id == 'view_count' || (BODY.where.includes && BODY.where.id.includes('view_count'))) ) {
-          var view_count = awe.settings.view('view_count') ? awe.settings.view('view_count').value() : 'mono';
-          
-          var event = new CustomEvent('view_count_changed', {detail: view_count});
-          window.dispatchEvent(event);
-        }
-        awe.resize_canvas(1);
-      };
-      
-      awe.renderers.add = function(BODY, HEAD) {
-        old_renderers_add.call(this, BODY, HEAD);
-        
-        var renderer = awe.renderer(),
-          container_element = renderer.get_canvas().parentNode,
-          three_renderer = renderer.get_three_renderer();
-        
-        vr_effect = new THREE.VREffect(three_renderer, function(error) {
-          if (error) {
-            vr_effect_supported = false;
-            console.warn(error);
-            
-            stereo_effect = new THREE.StereoEffect(three_renderer);
-            stereo_effect.separation = 0.8;
-            stereo_effect.setSize(container_element.clientWidth, container_element.clientHeight, false);
-            
-            three_renderer.autoClear = true;
-            
-            awe.scene_needs_rendering = 1;
-            if (enabled) {
-              var view_mode = awe.settings.view('view_mode') ? awe.settings.view('view_mode').value() : 'vr';
-              adapt_view_mode(view_mode);
-            }
-          }
-        })
-        
-        
-      };
-      
-      awe.render = function() {
-        var view_count = awe.settings.view('view_count') ? awe.settings.view('view_count').value() : 'mono';
-        
-        if (enabled && view_count == 'stereo' && awe.scene_needs_rendering && awe.pov()) {
-          if (vr_effect_supported) {
-            vr_effect.render(awe.scene().get_three_scene(), awe.pov().get_mesh());
-            awe.scene_needs_rendering = 0;
-            return;
-          }
-          if (stereo_effect) {
-            awe.renderer().get_three_renderer().autoClear = false;
-            stereo_effect.render(awe.scene().get_three_scene(), awe.pov().get_mesh());
-            awe.scene_needs_rendering = 0;
-            return;
-          }
-        }
-        old_render();
-        
-      };
-      this.registered = true;
-    },
-    unregister: function(plugin_data){
-      console.log('unregister')
-      this.registered = false;
-      awe.renderers.add = old_renderers_add;
-      awe.render = old_render;
-      awe.resize_canvas = old_resize_canvas;
-      awe.settings.update = old_settings_update;
-    },
-    enable: function(){
-      enabled = true;
-      var view_mode = awe.settings.view('view_mode') ? awe.settings.view('view_mode').value() : 'vr';
-      adapt_view_mode(view_mode);
-    },
-    disable: function(){
-      console.log('disable')
-      enabled = false;
-      var three_renderer = awe.renderer().get_three_renderer();
-      three_renderer.autoClear = true;
-      awe.resize_canvas(1);
-    },
-    api: {
-      get_stereo_cameras: function(){
-        var cameras = {};
-        if (stereo_effect) {
-          cameras = stereo_effect.getCameras();
-        }
-        else if (vr_effect) {
-          cameras = vr_effect.getCameras();
-        }
-        return cameras;
-      } 
-    }
-  }]);
-
-})(window.awe);
diff --git a/package.json b/package.json
deleted file mode 100644
index 49aedf2..0000000
--- a/package.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
-  "name": "awe.js",
-  "version": "1.0.0",
-  "description": "The jQuery for the Augmented Web",
-  "main": "index.js",
-  "directories": {
-    "example": "examples"
-  },
-  "scripts": {
-    "test": "echo \"Error: no test specified\" && exit 1"
-  },
-  "repository": {
-    "type": "git",
-    "url": "git+https://github.com/awe-media/awe.js.git"
-  },
-  "keywords": [
-    "awe.js",
-    "AR",
-    "VR",
-    "virtual",
-    "augmented",
-    "reality"
-  ],
-  "author": "npm@awe.media",
-  "license": "MIT",
-  "bugs": {
-    "url": "https://github.com/awe-media/awe.js/issues"
-  },
-  "homepage": "https://github.com/awe-media/awe.js#readme"
-}
